如果我创建一个名为TypeScript module
的简单test
,它将如下所示:
module test
{
export class MyTest {
name = "hello";
}
}
生成的JavaScript
会创建一个IIFE
,如下所示:
var test;
(function (test) {
var MyTest = (function () {
function MyTest() {
this.name = "hello";
}
return MyTest;
})();
test.MyTest = MyTest;
})(test || (test = {}));
我无法理解的是IIFE
末尾包含function
参数的以下行的目的是什么:
(test || (test = {}));
结果函数也接受参数test
:
(function (test) {
我理解在使用传递的参数时说出jQuery
这样的})(jquery);
对象,结果函数可以使用(function ($) {
这样的别名。但是,我只是没有看到(test || (test = {}));
参数的目的。
我理解test.MyTest = MyTest;
正在公开公共方法MyTest
,但为什么(test || (test = {}));
以及这些参数如何运作?
答案 0 :(得分:5)
它允许您使模块开放。例如
(function (test) {
var MyTest = (function () {
function MyTest() {
this.name = "hello";
}
return MyTest;
})();
test.MyTest = MyTest;
})(test || (test = {}));
(function (test) {
var SecondTest = (function () {
function SecondTest() {
this.name = "hello";
}
return SecondTest;
})();
test.SecondTest= SecondTest;
})(test || (test = {}));
第一次test
将undefined
,因此会被分配{}
。下次它已经定义,这就是我们用SecondTest
答案 1 :(得分:4)
它是一种扩展已存在对象的方法,或者如果尚未定义则最初定义它。让我们分解吧。
var test;
此行声明变量test
,以便稍后使用时,它不会抛出ReferenceError
。它的值可以是undefined
,也可以是test
已有的值。
(test || (test = {}))
如果test
是真实的(即test
),则此部分会传递undefined
的值,或者将test
分配给新对象,并将该对象传递给功能。这样,使用此代码的每个文件都可以扩展公共名称空间对象,而不是覆盖名称空间。
答案 2 :(得分:1)
这有帮助吗?
var test;
function IIFE(test) {
var MyTest = (function () {
function MyTest() {
this.name = "hello";
}
return MyTest;
})();
test.MyTest = MyTest;
}
test = test || {}
IIFE(test);
由于var test
被拉到顶部并且没有"取消分配"或覆盖任何现有的test
,如果测试定义在与IIFE相同的范围内,则将使用它而不是空对象。
答案 3 :(得分:1)
扩展其他人所说的内容并回答其他一些内联问题:
通过“开放式”,它们指的是能够在以后继续向对象添加成员的能力。如果你只能创建&扩展单个源文件中的对象,然后我们可以保证初始化的顺序并使代码更简单,但是你可以在script1.ts和script2.ts中使用以下代码,并以任何顺序将它们包含在页面中,因此,当脚本运行时,我们无法知道M1是否已初始化。
<强> script1.ts 强>
module M1 {
export module M2 {
export function F1(){return 42;}
}
}
<强> script2.ts 强>
module M1 {
export module M2 {
export function F2(){return "test";}
}
}
虽然重新声明变量是没有吸引力的,但它是无害的(见http://es5.github.io/#x10.5)。初始化之前的值是'undefined',这意味着表达式“M1 ||(M1 = {})”的第二部分被评估并返回,并且新初始化的对象在第一次被击中时作为参数传递,否则,表达式开头的现有值将作为后续声明的参数传递。
我故意在我的示例中使用嵌套模块来表明这不仅适用于变量,也适用于对象的属性。为上面的“script1”文件生成的代码(和“script2”类似)是:
<强> script1.js 强>
var M1;
(function (M1) {
var M2;
(function (M2) {
function F1() {
return 42;
}
M2.F1 = F1;
})(M2 = M1.M2 || (M1.M2 = {}));
})(M1 || (M1 = {}));
这里嵌套模块M2作为立即函数的参数提供为“M1.M2 ||(M1.M2 = {}”,如果它存在,它再次提供M1.M2的现有值,否则初始化它是一个空对象然后提供这个。这个对象属性,代表模块M1.M2,由嵌套函数内的参数M2引用,然后在它上面添加更多成员(它的导出)。
我希望这有助于澄清。