可能重复:
What advantages does using (function(window, document, undefined) { … })(window, document) confer?
我越来越多地在我一直在使用的库中看到这样的代码:
(function (window) {
var Foo = function () {
}
window.Foo = Foo;
})(window);
我看到这样做的论点是避免在创建(伪)类时在全局范围内工作。但是,如果我错了,请纠正我,我始终明白窗口是全球范围的。我相信,当你创建一个全局变量时,你实际上只是向窗口添加一个属性......除非ES5严格改变了吗?
所以,基本上,重点是什么?我可以看到像这样组织的代码的唯一好处是,如果你想通过传入窗口以外的参数来稍后更改类的命名空间。
答案 0 :(得分:2)
事实上,如果您忘记使用var
进行任何变量声明, strict mode 会抛出异常。但即使不使用外部封闭也可以。
使用此模式可以更好地保护自己免受外部javascript世界的侵害。例如,某些其他脚本会覆盖 window.undefined 或任何其他变量,您可以获取该闭包内的值以从内部保存访问它。
例如
(function _myApp( win, doc, undef ) {
// app code
}( this, this.document ));
此外,在使用 var 声明变量或创建函数声明时,这些变量始终存储在当前激活对象中 >词汇环境记录。这意味着,在不使用 Function上下文的情况下,您可以轻松地从其他方面覆盖方法和变量,因为所有这些都将存储在当前的 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 ,但如果你使用相同的代码,没有功能上下文,我们显然会覆盖我们的myVar
和myFunc
。这可能发生在所有地方,同一文件或其他加载的脚本中。
答案 1 :(得分:0)
像全局变量一样邪恶,你需要至少有一个或者没有办法访问你的脚本。您提供的代码是创建一个全局变量的一种方法。我更喜欢这种方式:
window.Foo = (function () {
var func = function () {
// ...
};
return {
func: func
};
})();
答案 2 :(得分: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();