我有一个javascript类,每个方法都返回一个Q
承诺。我想知道this
和method2
中method3
未定义的原因。有没有更正确的方法来编写这段代码?
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
?
答案 0 :(得分:119)
// keyboard down window check.
window.addEventListener("keydown", function(event) {
onKeyDownHandler(event);
}, false);
function onKeyDownHandler(e)
{
e.preventDefault();
var focus_id = e.target.id;
switch (e.keyCode) {
case 46: // delete
//delete item
alert("why i cant get this work on mac?");
break;
}
}
始终是调用方法的对象。但是,将方法传递给this
时,您没有调用它!该方法将存储在某处并在稍后从那里调用。如果你想保留then()
,你必须这样做:
this
或者如果你必须以ES6之前的方式进行,你需要在{I}之前保留.then(() => this.method2())
:
this
答案 1 :(得分:18)
默认情况下,在全局对象(window
)的上下文中调用Promise处理程序。在严格模式(use strict;
)下,上下文为undefined
。这就是method2
和method3
发生的事情。
;(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
内的上下文是实例的原因。
答案 2 :(得分:2)
基本上,您传递了一个没有上下文引用的函数引用。 #resultsRepeaterGrid tr[class="row"],tr[class="altrow"]
上下文的确定方式有以下几种:
this
,则myObj.f()
将成为myObj
背景。** this
和.bind
。这些是您明确说明.apply
上下文的内容。这些始终优先于前两个。在您的示例中,您传递了一个函数引用,因此在它的调用中,它隐含为全局函数或没有上下文的函数。使用this
可以通过创建一个显式设置.bind
的新函数来解决此问题。
*仅在非严格模式下才是这样。在严格模式下,this
设置为this
。
**假设您使用的功能尚未手动绑定。
答案 3 :(得分:0)
单向函数获取其上下文(this
)来自调用它们的对象(这就是为什么method1
具有正确的上下文 - 它在{{1}上调用的原因})。您正在将函数本身的引用传递给this
。您可以想象then
的实现看起来像这样:
then
在该示例中,function then( callback ) {
// assume 'value' is the recently-fulfilled promise value
callback(value);
}
是对您的函数的引用。它没有任何背景。正如您已经注意到的那样,在将函数传递给上下文之前,您可以通过将函数绑定到上下文来解决这个问题。