更新
为了清楚起见:@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);
记录为真等等......但我想知道实际上是什么,以及它是如何工作的(在所有级别上)。
我已准备好接受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
在我看来,这可能是黑客和陷阱的根源。更重要的是:它很难确定调用的来源:如果从全局对象(foo()
)调用window.foo();
,那么该上下文当然不会传递给{{1} },除非使用bar
bar
我之所以想要切割&确定调用者上下文的干燥,安全和可靠的方法很简单:我使用闭包来避免那些讨厌的全局变量,但同时我设置了几个函数作为事件处理程序。
我知道不使用严格模式,或者设置全局是容易修复的,但是严格的模式仍然存在,我喜欢它给聚会带来的东西(好吧,大部分)。我坚信这就是JS将要发展的方式,我不愿意发现自己因为不想打扰bar.apply(this,[]);
而烦恼我自己的代码。这可能不会太快发生,但我只是想让我的知识保持最新。
我已经阅读了strict
上的MDN页面,以及John Resig的博文,我看了很多DC的视频,并阅读了很多他的文章,我还没有找到明确的我上面描述的行为的解释。我没有读完整个ECMAScript标准(男孩,那东西太干了,它可能会耗尽撒哈拉沙漠),但也许这里有人可以指出我正确的方向来帮助我更好地理解这一点。
答案 0 :(得分:2)
我不确定我是否正确地阅读了您的问题,但似乎您在func.apply(context, arguments)
可以将context
作为参数的事实上遇到麻烦在函数内部由this
引用。
我认为传递上下文是必要的,如果没有它,JavaScript就无法正常工作。
从头到尾,因为没有super
正确使用继承的唯一方法就是使用像BaseClass.prototype.baseFunction.apply(this, arguments)
这样的东西。
删除该功能会创建一种与当今JavaScript非常不同的语言,而不是strict
模式的语言。