javascript - 为什么 TypeScript 会为类生成 IIFE?

标签 javascript class typescript

<分区>

查看此 TypeScript 代码:

class Greeter {
    greet() {}
}

它围绕构造函数和所有原型(prototype)函数声明生成一个 IIFE(立即调用函数表达式),例如:

var Greeter = (function () {
    function Greeter() {
    }
    Greeter.prototype.greet = function () { };
    return Greeter;
}());

这里的优势是什么?每当我读到 IIFE 时,我都会看到很多关于定义模块的用法。据我所知,Typescript 不会在 IIFE 中生成任何会污染全局命名空间的内容。

在我看来,这个类声明没有任何优势:

var Greeter = function () {}
Greeter.prototype.greet = function () { };

这是什么原因?

最佳答案

避免全局命名空间污染。

这是一个闭包模式,内部函数可以访问它们的父属性。通过 IIFE,返回对内部函数的引用。

下面是两个场景,其中 IIFE 模式非常有用,以及 TypeScript 编译器生成 IIFE 模式的原因:

  1. 继承实现:将 BaseClass 作为参数传递给 IIFE。如果 IIFEE 不存在,BaseClass 将成为全局变量,从而污染全局命名空间。

typescript :

class Greeter extends BaseController {
    greeting: string;
    constructor(message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
}

JS:

var Greeter = (function(_super) {
    __extends(Greeter, _super);

    function Greeter(message) {
        this.greeting = message;
    }
    Greeter.prototype.greet = function() {
        return "Hello, " + this.greeting;
    };
    return Greeter;
}(BaseController));
  1. 模块模式实现:其中应用程序只有一个全局变量,如“app”,所有其他功能都包装到对象中,如 app.cartapp.catalog 等。只有变量通过模块公开,所有其他功能都添加到模块本身,这只能通过 IIFE 实现。

typescript :

module App.Controller {
    export class Greeter extends BaseController {
        greeting: string;
        constructor(message: string) {
            this.greeting = message;
        }
        greet() {
            return "Hello, " + this.greeting;
        }
    }
}

JS:

var App;
(function (App) {
    var Controller;
    (function (Controller) {
        var Greeter = (function (_super) {
            __extends(Greeter, _super);
            function Greeter(message) {
                this.greeting = message;
            }
            Greeter.prototype.greet = function () {
                return "Hello, " + this.greeting;
            };
            return Greeter;
        }(BaseController));
        Controller.Greeter = Greeter;
    })(Controller = App.Controller || (App.Controller = {}));
})(App || (App = {}));

将此 js 代码复制/粘贴到浏览器控制台,只会全局创建 App 变量。其余功能将在 App 下。

谢谢, 做爱

关于javascript - 为什么 TypeScript 会为类生成 IIFE?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36217183/

相关文章:

javascript - 如何创建一个可以自然键入的输入字段,然后将其转换为 HTML?

c++ - 尝试在 C++ 中输出数组对象

javascript - Android 通过 HTML5/CSS3/JavaScript

java - 给定 int top、bottom、left 和 right,如何横穿 2D 数组?

c++ - 如何在 C++ 中访问 vector 中的子实例

javascript - 在 TypeScript 中向 Object.prototype 添加自定义方法

javascript - Angular2 创建组件

javascript - MatDatepicker : No provider found for DateAdapter. 您必须在应用程序根目录中导入以下模块之一:MatNativeDateModule

javascript - ng-if 不在 ng-repeat 中比较 $index

javascript - 用颜色填充线条之间的区域 - Three.js