this
这是理解(双关语)的好方法:
函数内部的值this
由调用函数的方式决定。除了一个例外,它与函数的定义位置、它可能嵌套在其中的其他函数、它被定义为哪个对象、它是什么类型的函数或任何其他函数无关。
foo.bar()
当您使用类似or的方法调用来调用函数时foo[bar]()
,this
函数内部就是foo
对象。
当您使用普通函数调用(如 )调用函数时foo()
,this
函数中是window
对象,或者如果函数使用严格模式,则它是undefined
。
这是一个例外——如果函数本身或其周围的代码对于普通函数调用进行了"use strict";
更改。this
对于不应该有所作为的好代码 - 你不应该编写依赖于this
对象window
的代码。
否则,您关心的是this
方法调用中的对象指的是什么。这始终取决于函数的调用方式,而不是它的定义方式。
让我们来看看你的第一个例子。
当您调用 时a.b()
,您是b
作为a
对象的方法调用的。所以在b
函数内部,this
与a
.
碰巧的是,知道这一点对我们没有任何好处,因为该b
函数永远不会对this
. 它所做的只是c()
作为普通函数调用。所以 inside c
,this
是对象,或者如果您处于严格模式window
,它会是对象。undefined
该c
函数只是返回它的this
值,或window
。这也是 的返回值b
。所以这就是你看到window
结果的原因:这一切都来自代码如何调用b
andc
函数。
现在关于第二个例子:嗯,那只是非常模糊的代码,不是吗?谁会编写这段代码并期望任何人一眼就能理解它?
所以让我们把它变成一种更易读的形式。这条线是问题所在:
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
嘿!这段代码是不是很眼熟?事实上,除了temp
变量名之外,它与第一个示例相同。所以现在你明白为什么它和第一个一样了。