为什么在使用 promise 时,类方法中的 “this” 未定义?

2022-08-30 04:58:57

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

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


答案 1

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

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

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

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

答案 2

默认情况下,在全局对象 () 的上下文中调用 Promise 处理程序。在严格模式 () 下时,上下文为 。这就是 和 所发生的情况。windowuse strict;undefinedmethod2method3

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

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

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