什么是「;x=x |{}”;JavaScript中的技术-它如何影响这种生活?
首先,一个伪代码示例:什么是「;x=x |{}”;JavaScript中的技术-它如何影响这种生活?,javascript,syntax,iife,Javascript,Syntax,Iife,首先,一个伪代码示例: ;(function(foo){ foo.init = function(baz) { ... } foo.other = function() { ... } return foo; }(window.FOO = window.FOO || {})); 这样称呼: FOO.init(); 我的问题: 什么是:window.FOO=window.FOO | |{}的技术名称/说明 我理解代码的作用。。。请参阅下文,了解我的提问原因
;(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 || {}));
我看到了一个最近的(很棒的)例子,他们称之为“exports
”:
我想我只是想标准化我的编码惯例。。。我想知道职业选手做什么,他们怎么想(这就是为什么我在这里问的) 图案
您描述的模式没有正式名称,因为它是三个单独的模式的组合。每个模式都有多个名称,但在本文中,我将使用以下术语:
- 关闭
- 别名
- 命名空间扩展
闭包
。它只是一个函数,用于限定变量和函数的范围,以使它们不会污染全局命名空间:
不结案
闭包,在本例中为
将变量保留在闭包中的优点是,您不必担心有人会覆盖您正在使用的变量。对于经常使用的临时变量,如i
或j
,这一点尤为重要
别名
此模式的第二个重要部分是别名。别名允许在闭包中定义和使用变量,而无需担心它所在的全局命名空间
无别名
带别名
这一点尤其重要,因为这意味着可以通过在单个位置更改名称来跨大型JavaScript文件更改全局名称空间。这是件好事™. 此外,缩小器可以将内部别名缩短为单个字母的变量名,如a
,从而在缩小时节省大量字节
命名空间扩展
命名空间扩展模式依赖于or运算符的合并行为(| |
)。在许多语言中,&
和|
返回true
或false
,但在JavaScript中,&
返回第一个false
值(false
,0
,
,null
,未定义的
),和|
返回第一个truthy
值(任何不是错误的值)。对于这两个运算符,如果未找到相应的类型,则返回最后一个参数。这使得|
操作符成为定义新名称空间的一种方便方法,仅当它不存在时
没有命名空间扩展
使用命名空间扩展
这很有用,因为它允许使用其他属性和方法扩展命名空间,而不必担心属性和方法的定义顺序
在第一个示例中,FileA
需要在FileB
之前执行:
FileA.js
FileB.js
在第二个示例中,File1
和File2
可以按任意顺序执行:
File1.js
File2.js
现在一起
将每个模式一起使用可创建一个非常强大的模块化脚本:
//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 || {}));
我一直把它理解为
至于影响你的生活,如果它已经被实例化,你将传入window.FOO
,如果它没有实例化,则传入一个空对象
您也可以将其理解为:
window.FOO = window.FOO || {};
;(function(foo){
foo.init = function(baz) { ... }
foo.other = function() { ... }
return foo;
}(window.FOO));
就我个人而言,我更喜欢不同的模式:
var FOO;
if (!FOO) {
FOO = {};
}
(function () {
"use strict";
FOO.prop1 = 'bar';
FOO.bar = function (z) {
return z + 1;
};
}());
我发现它不那么令人困惑,并帮助我确保干净的名称空间。为了补充pete的答案,另一种形式是:
;(function() {
var Foo = window.Foo = window.Foo || {};
Foo.foo = 'bar';
Foo.baz = function() {
return "Hello World!";
};
})();
我通常使用localvar
来给minifier节省几个字节的机会。当您在命名空间的多个层次上工作时,这会产生更大的影响,例如var MyView=window.MyApp.Views.MyView
正如其他人所指出的,您的第一个问题完全独立于第二个问题。它们之间没有任何关系,只是您决定将它们合并到一个语句中,而不是两个语句中
对于第一个问题,Douglas Crockford将其称为默认赋值。如中所示,如果变量存在,则不使用它,否则将其初始化为指定的默认值。当您看到类似以下内容的内容时:
foo = foo || {};
你的思维应该是这样的:
foo defaults to `{}`
从技术上讲,它实际上是“如果foo是falsy,那么将{}
赋值给foo”,但是我们假设任何falsy,比如零、null或未定义的值,在我们使用它时,都是对foo
无效的值。此外,单词default
已经暗示“如果未定义foo”
但是,说到这里,知道了你的第二个问题,很明显,default作为传递给你的iLife的参数的名称并不是一个合适的词。该参数所做的只是将方法和属性附加到传入的对象。在这种情况下,导出是合适的,如“这些是对象的公开导出成员”。我认为,attach也是一个合适的名称,如“将这些东西附加到对象”。我个人的偏好是简单地将它命名为object,这是您希望传入的类型。您可以调用参数FOO
。这将隐藏window.FOO
,除非您使用window.FOO
显式引用它。它们是相同的对象。请随意给同一个名字或不同的名字<代码>警报(window.FOO==FOO);
if (typeof window.Foo === 'undefined') {
window.foo = {};
}
window.foo = window.foo || {};
window.foo = {};
window.foo.bar = 'baz';
window.foo.fizz = 'buzz';
window.foo = window.foo || {};
window.foo.bar = 'baz';
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 || {}));
window.FOO = window.FOO || {};
;(function(foo){
foo.init = function(baz) { ... }
foo.other = function() { ... }
return foo;
}(window.FOO));
var FOO;
if (!FOO) {
FOO = {};
}
(function () {
"use strict";
FOO.prop1 = 'bar';
FOO.bar = function (z) {
return z + 1;
};
}());
;(function() {
var Foo = window.Foo = window.Foo || {};
Foo.foo = 'bar';
Foo.baz = function() {
return "Hello World!";
};
})();
foo = foo || {};
foo defaults to `{}`