更新
为清楚起见:@FelixKing:是的,我希望this
在调用时仍然未定义window.foo()
,原因如下:因为,在 JavaScript 中:
function foo()
{
console.log('I am a function');
}
(几乎)与以下内容相同:
var foo = function()
{
console.log('I am a function');
}
并foo === window.foo
评估为真,我希望他们都表现得一样。如果函数是变量,并且 JS 回退到全局对象(在函数 x 内部,变量未声明但您使用它,JS 会冒泡通过所有范围,直到全局对象,直到找到有问题的变量,或者它在全局级别上创建它),是否预先指定window
对象无关紧要。然而,当你这样做时,行为会发生变化,这是我没想到的。
对于为什么会出现这种情况,我有一种直觉(我定义的是方法,而不是变量),但话又说回来,对于全局对象,它们之间几乎没有区别。var c = 'Variable'; console.log(window.c === c);
记录真实等...但我想知道什么区别实际上是,以及它是如何工作的(在所有级别上)。
我已经准备好接受这一点,foo.apply(this,[]);
或者foo.apply(window,[]);
允许你强制this
指向全局对象,但不是window.foo();
. 如果严格是为了保护全局对象,我会说这会让后门大开。例如,我偶尔会发现自己调用函数,具体取决于变量的值。为此,我使用window[myVar]();
,无论是否严格,这意味着this
将指向全局对象,而如果我直接调用该函数,则不会。也就是说,在我看来,不一致。
我this
在严格模式下遇到了关键字的一些奇怪行为。不要误会我的意思,我知道在严格的函数中this
是未定义的。我发现令人困惑的是,它可以被迫指向全局对象(或任何其他对象,就此而言),有效地破坏了严格模式提供的安全网。这也有其他含义。考虑这段代码:this
'use strict';//using strict everywhere
(function(Global)
{
var closureObject = {};
Global.foo = function()
{
closureObject.setIn = closureObject.setIn || 'Set in foo';
console.log(this);
console.log(this === Global);
bar();
bar.apply(this);
return (this !== Global ? this : undefined);
};
Global.bar = function()
{
closureObject.setIn = closureObject.setIn || 'set in bar';
console.log(this);
return (this !== Global ? this : undefined);
};
})(this);
var undef = (Math.ceil(Math.random()*10)%2 ? foo() : bar());
foo();//undefined --- false --- undefined --- undefined
window.foo();//Window --- true --- undefined --- window
foo.apply(this,[]);//same as window.foo
同样适用于自定义对象:
function Foo(n)
{
this.name = n;
}
Foo.prototype.func = foo;//or window.foo
//other objects:
var d = new Date();
foo.apply(d,[]);//Date --- false --- undefined --- date
在我看来,这可能是黑客和陷阱的来源。更重要的是:这使得确定调用的来源变得相当困难:如果foo()
从全局对象 ( window.foo();
) 调用,则该上下文当然不会传递给bar
,除非bar
使用调用bar.apply(this,[]);
我可能想要一种简单明了、安全可靠的方法来确定调用者上下文的原因很简单:我使用闭包来避免那些讨厌的全局变量,但同时我正在设置几个充当事件处理程序的函数。
我知道不使用严格模式或设置全局是很容易解决的问题,但是严格模式会一直存在,我喜欢它给聚会带来的东西(嗯,大部分)。我坚信这是 JS 将要发展的方式,我不想因为不想打扰strict
. 这可能不会很快发生,但我只想让我的知识保持最新。
我已经阅读了 上的 MDN 页面strict
以及 John Resig 的博客文章,我看过不少 DC 的视频并阅读了很多他的文章,但我还没有找到对我上面描述的行为的明确解释。我还没有通读整个 ECMAScript 标准(天哪,那些东西太干了,它可能会耗尽撒哈拉沙漠),但也许这里有人可以为我指出正确的方向,以帮助我更好地理解这一点。