来自 TypeScript 模块的 JavaScript IIFE 中的默认参数的目的是什么?

What are the purpose of default arguments in JavaScript IIFE from a TypeScript module?

本文关键字:参数 是什么 默认 IIFE TypeScript 模块 JavaScript 来自      更新时间:2023-09-26

如果我创建一个名为test的简单TypeScript module,它将如下所示:

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

我无法理解的是包含function参数的IIFE末尾的以下行的目的是什么:

(test || (test = {}));

生成的函数还接受参数test

(function (test) {

我理解当使用参数传入时,比如说一个像})(jquery);这样的jQuery对象,并且生成的函数可以像(function ($) {一样采用别名。但是,我只是没有看到(test || (test = {}));论点的目的。

我知道test.MyTest = MyTest; MyTest公开了公共方法,但为什么要(test || (test = {}));以及这些论点如何工作?

它允许您使模块开放。

例如
(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

它是一种扩展现有对象的方法,或者如果尚未定义,则最初定义它。让我们分解一下。

var test;

此行声明变量 test 以便以后使用时不会抛出ReferenceError。它的价值要么是undefined,要么是test已经拥有的任何价值。

(test || (test = {}))

如果test为真(即不undefined(,则本节传递 test 的值,或者将test分配给新对象,并将该对象传递给函数。这样,使用此代码的每个文件都可以扩展公共命名空间对象,而不是覆盖命名空间。

这有帮助吗?

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相同的范围内定义的,它将被用来代替空对象。

扩展其他人所说的话并回答您的其他一些内联问题:

通过"开放式",它们指的是以后继续向对象添加成员的能力。 如果你只能在单个源文件中创建和扩展一个对象,那么我们可以保证初始化的顺序并使代码更简单,但是你可以在script1.ts和script2.ts中拥有以下代码,并将它们以任何顺序包含在页面中,所以我们无法知道M1在脚本运行时是否已初始化。

脚本1.ts

module M1 {
    export module M2 {
        export function F1(){return 42;}
    }
}

脚本2.ts

module M1 {
    export module M2 {
        export function F2(){return "test";}
    }
}

虽然重新声明变量没有吸引力,但它是无害的(见 http://es5.github.io/#x10.5(。 初始化前的值为"未定义",这意味着表达式"M1 ||(M1 = {}("被计算并返回,并且新初始化的对象在第一次命中时作为参数传递,否则表达式开头的现有值作为后续声明的参数传递。

我特意在我的示例中使用了嵌套模块,以表明这不仅适用于变量,也适用于对象的属性。 为上面的"script1"文件生成的代码(以及类似的"script2"(为:

脚本1.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 引用,然后向其添加更多成员(其导出(。

我希望这有助于澄清。