我正在阅读Angus Croll understanding JS this博客并找到了这个
var a = {
b: function() {
var c = function() {
return this;
};
return c();
}
};
a.b();//window
在我看来,在调用c时,c在b里面。这应该是调用上下文(纠正我,如果我错了)。当它执行时,为什么c()的上下文(this)是窗口?
我在blog
中找到了另一个例子var a = {
b: function() {
return (function() {return this;})();
}
};
a.b(); //window
为什么b的上下文是窗口?匿名函数是否始终在全局上下文中运行?
答案 0 :(得分:2)
这是了解this
(双关语)的好方法:
函数内this
的值由函数调用的方式决定。除了一个例外,它与定义函数的位置,它可以嵌套在其中的其他函数,它被定义为哪个对象,它是什么类型的函数,或者其中任何一个都没有关系。
当您使用foo.bar()
或foo[bar]()
等方法调用来调用函数时,函数内的this
是foo
对象。
当您使用foo()
之类的普通函数调用调用函数时,函数中的this
是window
对象,或者如果函数使用严格模式,则为{{1} }。
这是一个例外 - 如果函数本身或其周围的代码有undefined
,它会更改"use strict";
以进行普通函数调用。对于不应该产生影响的优秀代码 - 您不应该编写依赖于this
作为this
对象的代码。
否则,您关心的是对象window
在方法调用中引用的内容。而且这总是取决于函数的调用方式,而不是它的定义方式。
让我们来看看你的第一个例子。
当您致电this
时,您正在调用a.b()
作为b
对象的方法。因此,在a
函数中,b
与this
相同。
碰巧的是,由于a
函数永远不会对b
做任何事情,因此我们没有任何好处。它只是将this
称为普通函数。因此,在c()
内,c
是this
对象,如果您处于严格模式,它将是window
。
undefined
函数只返回其c
值或this
。这也是window
的返回值。这就是为什么您看到b
的结果:这一切都来自代码如何调用window
和b
函数。
现在关于第二个例子:嗯,这只是非常模糊的代码,不是吗?谁会写这段代码并期望任何人乍看之下理解它?
因此,让我们把它变成一种更易阅读的形式。这一行是问题所在:
c
让我们取出带括号的函数表达式:
return (function() {return this;})();
并将其分配给临时变量:
(function() {return this;})
我们不再需要额外的括号,并且让代码缩进以便于阅读:
var temp = (function() {return this;});
我们可以将 var temp = function() {
return this;
};
变量称为temp
语句中的函数:
return
现在我们可以将它放回代码示例中的 return temp();
函数:
b
喂!该代码看起来不熟悉吗?实际上,除了var a = {
b: function() {
var temp = function() {
return this;
};
return temp();
}
};
a.b(); //window
变量的名称之外,它与第一个示例相同。所以现在你明白为什么它和第一个一样。
答案 1 :(得分:1)
要查找的一个关键字是new
关键字,它建立了一个新的上下文。看不到new
?然后上下文没有改变,这意味着this
没有改变。如果您从window
内拨打此电话,那就是您的上下文,那就是您的this
。 (如果您将call()
或apply()
与范围一起使用,则会发生变化,但这显然不适用于此处。)