4

可能重复:
使用 (function(window, document, undefined) { ... })(window, document) 有什么好处?

我越来越多地在我一直使用的库中看到这样的代码:

(function (window) {
    var Foo = function () {
    }

    window.Foo = Foo;
})(window);

我看到的这样做的论点是在创建(伪)类时避免在全局范围内工作。但是,如果我错了,请纠正我,我一直认为 window 是全局范围。我相信,当你创建一个全局变量时,你实际上只是在向窗口添加一个属性......除非这对 ES5 严格来说有所改变?

那么,基本上,有什么意义呢?我可以看到像这样组织的代码的唯一好处是,如果您想在以后通过传入除 window.xml 之外的参数轻松更改类的命名空间。

4

3 回答 3

3

事实上,如果您忘记使用任何变量声明,严格模式会引发异常。var但即使不使用外部封闭也可以。

使用这种模式更多地是为了保护自己免受外部 javascript 世界的影响。例如,一些其他脚本覆盖了 window.undefined或任何其他变量,您可以获取该闭包中的值以便从内部访问它。

例如

(function _myApp( win, doc, undef ) {
    // app code
}( this, this.document ));

此外,当使用var声明变量或创建函数声明时,它们始终分别存储在当前的激活对象中,即词法环境记录。这意味着,在不使用Function context的情况下,您可以轻松地从其他点覆盖方法和变量,因为所有这些都将存储在当前Context中(这将是全局的)

所以:

(function _myApp( win, doc, undef ) {
    var myVar = 42;

    function myFunc() {
    }
}( this, this.document ));

(function _myModule( win, doc, undef ) {
    var myVar = 42;

    function myFunc() {
    }
}( this, this.document ));

这是因为闭包Context起作用的,但是如果你使用相同的代码,没有Function Context,我们显然会覆盖我们的myVarand myFunc。这可能发生在任何地方,在同一个文件中或在另一个加载的脚本中。

于 2012-10-22T14:36:20.683 回答
0

与全局变量一样邪恶,您至少需要一个,否则无法访问您的脚本。您提供的代码是创建该全局变量的一种方法。我更喜欢这种方式:

window.Foo = (function () {
    var func = function () {
        //  ...
    };

    return {
        func: func
    };
})();
于 2012-10-22T14:36:35.237 回答
0

你是对的,但不同之处在于函数内部的代码就像一个自动init函数。

(function (window) {
    var Foo = function () {
    }

    var Bar = 69; // not in global scope

    window.Foo = Foo; // in global scope
})(window);

相对于

var Foo = function () { // in global scope
}

var Bar = 69; // in global scope

var Foo = function () { // in global scope
}

function init () {
    var Bar = 69; // not in global scope
}
init();
于 2012-10-22T14:37:16.487 回答