据我了解,函数的执行上下文(this)与声明的位置无关,而与调用的位置(调用站点)无关。考虑2种情况,其中foo在全局上下文中定义-
//1.
function foo(){ console.log(this); }
var obj = {
x: foo,
};
obj.x(); //prints obj because foo was called "on" obj object
//2.
function foo(){ return this; }
var obj = {
x: function(){ console.log(foo()); },
};
obj.x(); //prints window object.
我对第二种情况感到困惑。尽管我知道x函数的上下文是obj,但我无法理解在x函数内部foo对象是如何在 窗口对象上被调用的(其上下文实际上是obj)? 确保有关此主题有很多问题,我无法找到与此类示例相似的内容。谢谢。
答案 0 :(得分:0)
在第二种情况下,从x
的上下文调用在obj
对象中分配给obj
对象的函数,您可以通过在其中登录this
来测试功能。
var obj={
x:function() {
console.log(this); // prints obj
console.log(foo());
}
}
但是当您从此函数内部调用foo
时,它没有任何调用上下文,您就像在全局上下文中定义的任何其他函数以及在任何全局定义的函数{ {1}}指向this
对象,因此当您在window
函数中登录window
时,会在控制台上打印this
。
答案 1 :(得分:0)
我将尝试给出一个简短的答案:
函数的上下文通常是为其分配对象的对象。由于在第二种情况下,foo没有声明为对象的属性,因此它的上下文是全局(窗口)对象。
如果要将对象作为上下文传递给foo,则必须使用foo.call(this,... parameters)或foo.apply(this,parameters)进行调用,也可以使用绑定到对象的函数:
const myFoo = foo.bind(this);
myFoo(...parameters);
Here是一篇带有扩展说明的文章。
答案 2 :(得分:0)
正如其他答案和评论所解释的那样:如此调用foo时,您的执行上下文未绑定到obj
。正如您期望的那样,您可能会想说:
foo.call(obj)
基本上,您将foo中的this
绑定到对象obj
,它是第一个参数。
更多MDN