TypeScript模块中JavaScript IIFE中默认参数的用途是什么?

时间:2014-11-13 04:20:23

标签: javascript typescript iife

如果我创建一个名为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 = {}));以及这些参数如何运作?

4 个答案:

答案 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 = {}));

第一次testundefined,因此会被分配{}。下次它已经定义,这就是我们用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引用,然后在它上面添加更多成员(它的导出)。

我希望这有助于澄清。