问题描述
当我将 this
函数的上下文设置为与对象 window
一起运行时,我不明白为什么 f6
值是 obj
对象。
let obj = {
color: "blue",name: "maya"
};
function f6() {
return function() {
console.log(this);
}
}
f6.call(obj)();
解决方法
在 function
函数中,this
不是由词法作用域决定的。
它由函数的调用方式和上下文决定。
每个 function
函数都会创建自己的 this
绑定环境。
function f(){
this; // This `this` is distinct …
function g(){
this; // … from this `this`.
}
}
function f(){
console.log(this);
}
const objX = {
f
},objY = {};
objX.f(); // Logs `objX`,because the expression `objX.f` is a member of a reference.
f(); // No `this` binding. `f` by itself isn’t the member of a reference.
f.call(objY); // Logs `objY`,because `this` was explicitly set.
另一方面,箭头函数从它们的词法作用域获取 this
绑定。
箭头函数不会创建自己的 this
绑定环境。
function f(){
this; // This `this` is the same …
() => {
this; // … as this `this`.
};
}
您使用 f6
调用 .call
以提供 this
绑定。
这就是 f6
函数从中获取其 this
值的地方,但 f6
不使用其 this
值。
与此无关,f6
返回一个碰巧使用 this
的函数。
同样,它是一个 function
函数,因此它的 this
绑定取决于调用。
如果您想知道返回函数的 this
值是什么,您必须检查调用:
f6.call(obj)();
// Equivalent to:
(f6.call(obj)) ();
// -^^^^^^^^^^^^- Returned function.
// ^^ Call.
.call
或 .apply
未用于返回的函数,且未使用 .bind
,因此未明确设置 this
绑定。
(f6.call(obj))
也不是带有引用成员的表达式(即 MemberExpression)。
调用是在没有提供上下文的情况下执行的,因此上下文将是 globalThis
或严格模式下的 undefined
。
使用箭头函数可以解决这个问题:
function f6(){
return () => console.log(this);
}
f6.call(obj)(); // Logs `obj`.
或者,在返回中使用 .bind
也可以解决此问题:
function f6(){
return function(){
console.log(this);
}.bind(this);
}
f6.call(obj)(); // Logs `obj`.
当然,使用是词法范围1的东西,即变量,也可以解决这个问题:
function f6(){
const that = this;
return function(){
console.log(that);
};
}
f6.call(obj)(); // Logs `obj`.
1:我想你可以说 this
也是词法范围的,但是被每个嵌套的 function
函数所掩盖。
另见: