为什么在使用 promises 时在类方法内部未定义“this”?

新手上路,请多包涵

我有一个 javascript 类,每个方法都返回一个 Q 承诺。我想知道为什么 thismethod2method3 中未定义。有没有更正确的方法来编写这段代码?

 function MyClass(opts){
  this.options = opts;

  return this.method1()
    .then(this.method2)
    .then(this.method3);
}

MyClass.prototype.method1 = function(){
  // ...q stuff...

  console.log(this.options); // logs "opts" object

  return deferred.promise;
};

MyClass.prototype.method2 = function(method1resolve){
  // ...q stuff...

  console.log(this); // logs undefined

  return deferred.promise;
};

MyClass.prototype.method3 = function(method2resolve){
  // ...q stuff...

  console.log(this); // logs undefined

  return deferred.promise;
};

我可以使用 bind 解决这个问题:

 function MyClass(opts){
  this.options = opts;

  return this.method1()
    .then(this.method2.bind(this))
    .then(this.method3.bind(this));
}

但不完全确定为什么 bind 是必要的;是 .then() 杀死 this 关闭?

原文由 SteamDev 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 418
2 个回答

this 始终是调用该方法的对象。但是,当将方法传递给 then() 时,您没有调用它!该方法将存储在某个地方并稍后从那里调用。如果你想保留 this ,你必须这样做:

 .then(() => this.method2())

或者,如果您必须以 ES6 之前的方式执行此操作,则需要在之前保留 this

 var that = this;
// ...
.then(function() { that.method2() })

原文由 lex82 发布,翻译遵循 CC BY-SA 3.0 许可协议

默认情况下,在全局对象 ( window ) 的上下文中调用 Promise 处理程序。在严格模式下( use strict; ),上下文为 undefined 。这就是 method2method3 发生的事情。

 ;(function(){
  'use strict'
  Promise.resolve('foo').then(function(){console.log(this)}); // undefined
}());

;(function(){
  Promise.resolve('foo').then(function(){console.log(this)}); // window
}());

对于 method1 ,您正在调用 method1 作为 this.method1() 。这种调用它的方式在 this 对象的上下文中调用它,该对象是您的实例。这就是为什么里面的上下文 method1 是实例。

原文由 Joseph 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题