更新
为了清楚起见:@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
评估为 true,我希望他们都表现得相似。如果函数是变量,并且 JS 回退到全局对象(在函数 x 内部,未声明变量但您使用它,则 JS 冒泡 遍历所有作用域,直到全局对象,直到它找到有问题的变量,或者在全局级别上创建它),如果指定 window
应该没有关系。是否预先反对。然而,当你这样做时,行为会发生变化,这是我没有预料到的。
我有一种直觉为什么会出现这种情况(我正在定义方法,而不是变量)但话又说回来,对于全局对象来说,它们之间几乎没有什么区别。 var c = 'Variable'; console.log(window.c === c);
记录 true 等...但我想知道实际上的区别是什么,以及它是如何工作的(在所有级别)。
我准备好接受这一点foo.apply(this,[]);
或foo.apply(window,[]);
让你强制this
指向全局对象,但不是window.foo();
。如果严格是为了屏蔽全局对象,我会说这会留下后门大开。例如,我偶尔会发现自己根据变量的值调用函数。为此,我使用 window[myVar]();
,无论严格与否,这意味着 this
将指向全局对象,而如果我直接调用该函数则不会。在我看来,这是一种不一致。
我遇到了 this
的一些奇怪行为严格模式下的关键字。别误会我的意思我知道this
是 undefined in strict functions 。我觉得令人困惑的是 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
在我看来,这可能是黑客攻击和陷阱的根源。更重要的是:这使得确定调用来自哪里变得相当困难:if foo()
从全局对象( window.foo();
)调用,该上下文当然不会传递给 bar
,除非bar
使用 bar.apply(this,[]);
调用
我可能想要一种简单、安全、可靠的方法来确定调用者上下文的原因很简单:我使用闭包来避免那些讨厌的全局变量,但同时我正在设置几个充当事件处理程序的函数。
我知道不使用严格模式或设置全局是很容易解决的问题,但严格模式将继续存在,我喜欢它给聚会带来的东西(嗯,大部分)。我坚信这就是 JS 发展的方式,我不想因为不想打扰 strict
而发现自己为自己的破损代码哭泣。 。这可能不会太快发生,但我只是想让我的知识保持最新。
我已阅读 strict
上的 MDN 页面以及 John Resig 的博客文章,我观看了相当多的 DC 视频并阅读了他的很多文章,但我还没有找到对我上面描述的行为的明确解释。我还没有通读整个 ECMAScript 标准(天哪,那东西太干了,它可能会耗尽撒哈拉沙漠的水),但也许这里有人可以给我指出正确的方向,帮助我更好地理解这一点。
最佳答案
我不确定我是否正确地阅读了您的问题,但似乎您对 func.apply(context, argument)
可以采用 的事实感到困难context
作为参数,然后由函数内的 this
引用。
我认为传递上下文是必要的,没有它 JavaScript 就无法正常工作。
在我的脑海中,由于没有super
,正确使用继承的唯一方法是使用BaseClass.prototype.baseFunction.apply(this,arguments)
.
删除该功能将创建一种与当今 JavaScript 非常不同的语言,而这不是严格
模式的含义。
关于javascript - JavaScript 严格模式下 "this"的行为不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12250609/