【问题标题】:ES6: this is undefined despite using bind()ES6:尽管使用了 bind(),但这是未定义的
【发布时间】:2016-04-15 19:18:21
【问题描述】:

注意:我正在使用 Babel 作为我的转译器

我正在尝试用一些私有方法的概念来实现一个 ES6 类。为此,我在类声明之外声明了一个函数,并且我还尝试将闭包用于 DRY 实践。

但是,当我的类方法调用“私有”方法时,this 的上下文变得未定义。我认为使用 bind() 应该显式设置上下文,但它似乎不起作用。

function _invokeHttpService(httpMethod) {
    return (url, config, retries, promise) => {
      var s = this;
      // Do some additional logic here...
      httpMethod(url, config)
        .then(
          response => {
            s._$log.info(`Successful response for URL: ${url}`);
            promise.resolve(response);
          },
          error => {
            s._$log.error(`Request for URL: ${url} failed.`);
            promise.reject(error)
          });
    }
  }

  function _get(url, config, retries, promise) {
    _invokeHttpService(this._$http.get);
  }

  class httpSessionService {
    /*@ngInject*/
    constructor($log, $http, $q, $timeout, CODE_CONSTANTS, $rootScope) {
      this._$log = $log;
      this._$http = $http;
      this._$q = $q;
      this._$timeout = $timeout;
      this._$rootScope = $rootScope;
      this._CODE_CONSTANTS = CODE_CONSTANTS;
    }

    get(url, config, retries = 5) {
      var s = this;
      var deferred = s._$q.defer();
      _get(url, config, retries, deferred).bind(this);
      return deferred.promise;
    }
  }

【问题讨论】:

    标签: javascript angularjs closures ecmascript-6


    【解决方案1】:

    bind 创建一个函数的副本,其中this 设置为第一个参数。

    var f = _get.bind(this);
    f(url, config, retries, deferred);
    

    您要使用的是call,它基本上是bind,但该函数会立即被调用。第一个参数是 this 的值,而后面​​的任何参数都将传递给您正在调用的函数。

    _get.call(this, url, config, retries, deferred);
    

    call 有一个名为 apply 的姊妹函数,它做同样的事情,但将实际参数放在一个数组中。

    _get.apply(this, [url, config, retries, deferred]);
    

    当您不确定要传递给函数的参数数量时很有用。

    【讨论】:

      猜你喜欢
      • 2012-03-15
      • 2015-08-30
      • 1970-01-01
      • 1970-01-01
      • 2016-11-01
      • 1970-01-01
      • 2023-02-14
      • 1970-01-01
      • 2016-06-01
      相关资源
      最近更新 更多