查看此 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 模式的原因:
- 继承实现:将
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));
- 模块模式实现:其中应用程序只有一个全局变量,如“app”,所有其他功能都包装到对象中,如
app.cart
、app.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 下。
谢谢,
做爱