为什么在使用类方法作为回调时以及使用"普通函数" 时Promise.then
传递执行上下文?undefined
window
类方法是否与其拥有的对象/类分离?为什么undefined
而不是window
?
function normal() { console.log('normal function', this); } const arrow = () => { console.log('arrow function', this); } function strictFunction() { 'use strict'; console.log('strict function', this); } class Foo { test() { this.method(); // Foo Promise.resolve().then(() => console.log('inline arrow function', this)); // Foo Promise.resolve().then(normal); // window Promise.resolve().then(arrow); // window Promise.resolve().then(strictFunction); // undefined Promise.resolve().then(this.method); // undefined <-- why? } method() { console.log('method', this); } } const F = new Foo(); F.test();
(jsFiddle)
我希望上下文this.method
丢失,但无法理解为什么this.method
"正常"和箭头功能之间的不同行为.
这种行为有规格吗?我发现的唯一参考是Promises A +,指的是"在严格的模式下this
将在undefined
里面;在草率模式下,它将是global object
." .
你在那里的引用告诉你为什么:
在严格模式下
this
将是未定义的; 在草率模式下,它将成为全局对象.
该ES6规范说:
ClassDeclaration或ClassExpression的所有部分都是严格模式代码
因此,由于严格模式,this
在一个未绑定的类方法中,将是undefined
.
class A {
method() {
console.log(this);
}
}
const a = new A();
a.method(); // A
const unboundMethod = a.method;
unboundMethod(); // undefined
这与Promise无关,而是与this
调用上下文有关。
情况1:
this.method(); // Foo
这method
是在Foo
类中定义的函数,因此this
被评估为触发该函数的对象,位于this
中this.method
。因此- Foo
显示。
情况2:
Promise.resolve().then(() => console.log('inline arrow function', this)); // Foo
箭头函数是ES6的一项功能,其独特的属性this
是定义所在上下文的上下文中的上下文。该函数是在上下文中调用的,this === Foo
这就是所显示的内容。
情况3:
Promise.resolve().then(normal); // window Promise.resolve().then(arrow); // window
由于箭头函数是箭头函数,所以箭头函数将其上下文保留为窗口,并且在没有上下文的情况下评估普通函数,在非上下文中将其this
评估为窗口strict mode
。
情况4:
Promise.resolve().then(strictFunction); // undefined
strict mode
在此函数的主体内,由于请求是在窗口中声明的,this
被评估为未定义。
情况5:
Promise.resolve().then(this.method); // undefined <-- why?
在此规范中,定义所有类代码均为严格代码:
ClassDeclaration或ClassExpression的所有部分都是严格模式代码。