off(name, callback, context) {
    let retain, ev, events, names, i, l, j, k
    if (!this._events || !eventsApi(this, 'off', name, [callback, context])) return this
    if (!name && !callback && !context) {
      this._events = void 0
      return this
    }
    names = name ? [name] : Object.keys(this._events)
    // jshint maxdepth:5
    for (i = 0, l = names.length; i < l; i++) {
      name = names[i]
      events = this._events[name]
      if (events) {
        this._events[name] = retain = []
        if (callback || context) {
          for (j = 0, k = events.length; j < k; j++) {
            ev = events[j]
            if ((callback && callback !== ev.callback && callback !== ev.callback._callback) ||
                (context && context !== ev.context))
              retain.push(ev)

          }
        }
        if (!retain.length) delete this._events[name]
      }
    }
    return this
  }
stop listening to an event
@method off
@param {String} name
@param {Function} callback
@param {Object} context