我试图弄清楚当将函数传递给数组的map
方法时,'this'是如何绑定的。
我有以下代码(你可以see on StackBlitz):
import './style.css';
class Foo {
public method() { return this ? `"this" is a ${this.constructor.name}`
: '"this" is undefined'; }
}
class Caller {
public method1(array) {
return array.map(function() { return foo.method(); });
}
public method2(array) {
return array.map(this.callMethod);
}
public method3(array) {
return array.map(foo.method);
}
public method4(array) {
return array.map(v => foo.method());
}
private callMethod() { return foo.method(); }
}
const foo = new Foo();
const caller = new Caller();
const array = [1];
document.getElementById('app').innerHTML = `
<dl>
<dt>Expected</dt>
<dd>${foo.method()}</dd>
<dt>Method 1 (anonymous function)</dt>
<dd>${caller.method1(array)}</dd>
<dt>Method 2 (class method)</dt>
<dd>${caller.method2(array)}</dd>
<dt>Method 3 (function reference)</dt>
<dd>${caller.method3(array)}</dd>
<dt>Method 4 (lambda function)</dt>
<dd>${caller.method4(array)}</dd>
</dl>
`;
这给出了以下输出:
Expected "this" is a Foo Method 1 (anonymous function) "this" is a Foo Method 2 (class method) "this" is a Foo Method 3 (function reference) "this" is undefined Method 4 (lambda function) "this" is a Foo
因此,除了直接引用函数成员之外的所有情况下,使用绑定到method
对象的this
调用Foo
方法。
我无法用MDN上的description的array.prototype.map
来说明这一点,它说:
如果提供thisArg参数进行映射,则它将用作回调的此值。否则,undefined值将用作此值。
在上述情况中,我没有明确提供thisArg
参数,那么为什么4种方法中的3种“起作用”?
PS。奖金问题:为什么,如果我注释掉第一行(import './style.css'
)这样做方法3突然也能正常工作?!!
在上述情况中,我没有明确提供thisArg参数,那么为什么4种方法中的3种“有效”?
你没有为thisArg
回调提供map
参数,但是你没有在this
回调中测试map
,你在this
中测试Foo.method
,在所有这三种方法中都被称为
foo.method()
这保证在method
内部这将是foo
(并且它与地图没有任何关系,这就是调用.
运算符的方法一般表现)。
PS。奖金问题:为什么,如果我注释掉第一行(导入'./style.css')这会让方法3突然工作吗?!!
那不是我所看到的。这是我删除import
声明时打印的内容:
"this" is a Window
这与non-strict mode一致,如果this
没有被函数接收,则qazxswpoi被设置为全局对象。