参见英文答案 > What does “var FOO = FOO || {}” (assign a variable or an empty object to that variable) mean in Javascript? 7个
首先,一个伪代码示例:
;(function(foo){
foo.init = function(baz) { ... }
foo.other = function() { ... }
return foo;
}(window.FOO = window.FOO || {}));
这样称呼:
FOO.init();
我的问题:
>什么是技术名称/描述:window.FOO = window.FOO || {}?
我理解代码的作用…请参阅下面的我的原因.
询问理由:
我这样称呼全球传递:
;(function(foo){
... foo vs. FOO, anyone else potentially confused? ...
}(window.FOO = window.FOO || {}));
…但我只是不喜欢称那个小写的“foo”,考虑到全球被称为大写FOO ……这看起来似乎令人困惑.
如果我知道这种技术的技术名称,我可以说:
;(function(technicalname){
... do something with technicalname, not to be confused with FOO ...
}(window.FOO = window.FOO || {}));
我见过一个最近(很棒)的例子,他们称之为“出口”:
;(function(exports){
...
}(window.Lib = window.Lib || {}));
我想我只是想把我的编码惯例标准化……我想了解专业人士做了什么以及他们如何思考(这就是我在这里问的原因)!
解决方法:
图案
(function (foo) {
...code...
foo.bar = baz;
...more code...
}(window.FOO = window.FOO || {});
您描述的模式没有正式名称,因为它是三个单独的模式组合在一起.每个模式都有多个名称,但对于这篇文章,我将使用以下术语:
>关闭
>别名
>命名空间扩展
关闭
整个模式的基础是闭包.它只是一个用于扩展变量和函数的函数,以便它们不会污染全局命名空间:
没有关闭
//these declare window.foo and window.bar respectively
//as such, they pollute the global namespace
var foo;
function bar() {}
关闭,在这种情况下,Immediately Invoked Functional Expression (IIFE)
(function () {
//these declare foo and bar within the function
//but they are not accessible outside the function
var foo;
function bar() {}
}());
将变量保存在闭包中的优点是,您不必担心有人会覆盖您正在使用的变量.这对于经常使用的临时变量(例如i或j)尤为重要.
别号
这种模式的第二个重要部分是别名.别名允许在闭包中定义和使用变量,而无需担心它所驻留的全局命名空间.
没有别名
(function () {
...
foo = window.SomeFunction(bar, baz);
...
}());
使用别名
(function (sf) { //local name
...
foo = sf(bar, baz);
...
}(window.SomeFunction)); //global namespace
这一点尤为重要,因为这意味着可以通过在单个位置更改名称来跨大型JavaScript文件更改全局命名空间.这是A Good Thing™.此外,缩小器可以将内部别名缩短为单个字母变量名称(例如a),从而在缩小时节省大量字节.
命名空间扩展
命名空间扩展模式依赖于或运算符(||)的合并行为.在许多语言中,&&和||返回true或false,但在JavaScript中,&&返回第一个falsey值(false,0,”,null,undefined)和||返回第一个truthy值(任何不是假的).对于两个运算符,如果未找到相应的类型,则返回最后一个参数.这使得|| operator只有在尚未存在的情况下才能定义新命名空间的便捷方式.
无命名空间扩展
if (typeof window.Foo === 'undefined') {
window.foo = {};
}
使用命名空间扩展
window.foo = window.foo || {};
这很有用,因为它允许使用其他属性和方法扩展名称空间,而不必担心属性和方法的定义顺序.
在第一个示例中,需要在FileB之前执行FileA:
FileA.js
window.foo = {};
window.foo.bar = 'baz';
FileB.js
window.foo.fizz = 'buzz';
在第二个示例中,File1和File2可以按任何顺序执行:
File1.js
window.foo = window.foo || {};
window.foo.bar = 'baz';
File2.js
window.foo = window.foo || {};
window.foo.fizz = 'buzz';
现在都在一起了
使用每个模式一起创建一个非常强大的模块化脚本
//use foo internally so that you don't have to worry about
//what the global namespace is called
(function (foo) {
//declare variables internally that you want to keep local to the script
var i,
len,
internal,
qux;
//declare functions/properties on the alias when you want to expose them
foo.bar = function () {...};
//extend the global namespace so that existing extensions are persistent
}(window.FOO = window.FOO || {}));