2

更新

为清楚起见:@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 标准(天哪,那些东西太干了,它可能会耗尽撒哈拉沙漠),但也许这里有人可以为我指出正确的方向,以帮助我更好地理解这一点。

4

1 回答 1

2

我不确定我是否正确地阅读了您的问题,但是您似乎对func.apply(context, arguments)可以将context其作为参数的事实感到麻烦,然后该参数将this在函数内部被引用。

我认为传递上下文是必要的,没有它 JavaScript 就无法正常工作。

在我的脑海中,因为没有super正确使用继承的唯一方法是使用类似BaseClass.prototype.baseFunction.apply(this, arguments).

删除该功能将创建一种与今天的 JavaScript 非常不同的语言,而这不是strict模式的意义所在。

于 2012-09-03T15:48:34.153 回答