使用promises时,为什么'this'在类方法中未定义?

Ste*_*Dev 89 javascript this node.js promise q

我有一个javascript类,每个方法都返回一个Qpromise.我想知道为什么this未定义method2method3.有没有更正确的方法来编写此代码?

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;
};
Run Code Online (Sandbox Code Playgroud)

我可以通过使用bind:

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

  return this.method1()
    .then(this.method2.bind(this))
    .then(this.method3.bind(this));
}
Run Code Online (Sandbox Code Playgroud)

但不完全确定为什么bind有必要; 正在.then()杀戮this

lex*_*x82 131

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

.then(() => this.method2())
Run Code Online (Sandbox Code Playgroud)

或者如果你必须以ES6之前的方式进行,你需要保留this之前:

var that = this;
// ...
.then(function() { that.method2() })
Run Code Online (Sandbox Code Playgroud)

  • 很好的答案 - 或者预先ES6".然后(this.method2.bind(this))" (5认同)
  • 我用`.then(data => this.method(data))` (5认同)

Jos*_*eph 19

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
}());
Run Code Online (Sandbox Code Playgroud)

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

  • 现在**这个**是一个答案**帮助我理解**它**。 (2认同)

Mik*_*uck 6

基本上,您传递给它的是一个没有上下文引用的函数引用。该this上下文在几个方面决定:

  1. 含蓄地。调用全局函数或没有绑定的函数假定全局上下文。*
  2. 通过直接引用。如果你打电话,myObj.f()那么myObj将是this上下文。**
  3. 手动装订。这是您的函数类,例如.bindand .apply。这些您明确说明this上下文是什么。这些总是优先于前两个。

在您的示例中,您正在传递一个函数引用,因此在调用它时,它暗示是一个全局函数或一个没有上下文的函数。Using.bind通过创建一个this明确设置的新函数来解决这个问题。

*这只适用于非严格模式。在严格模式下,this设置为undefined.

**假设您使用的函数没有被手动绑定。