为什么要在匿名 function() 调用中嵌入 JavaScript 类?
-
12-12-2019 - |
题
我正在阅读有关 Microsoft 的新的类似 JavaScript 的语言,称为 打字稿. 。在里面 游乐场(示例部分), ,有一个简单的类将 TypeScript 语法转换为 JavaScript 代码。来自 Java 编程背景的我,了解如何在从 TypeScript 编译的 JavaScript 中完成 OOP 对我来说很有趣。
打字稿代码:
class Greeter {
greeting: string;
constructor (message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
var greeter = new Greeter("world");
var button = document.createElement('button')
button.innerText = "Say Hello"
button.onclick = function() {
alert(greeter.greet())
}
document.body.appendChild(button)
以及等效的 JavaScript 代码:
var Greeter = (function () {
function Greeter(message) {
this.greeting = message;
}
Greeter.prototype.greet = function () {
return "Hello, " + this.greeting;
};
return Greeter;
})();
var greeter = new Greeter("world");
var button = document.createElement('button');
button.innerText = "Say Hello";
button.onclick = function () {
alert(greeter.greet());
};
document.body.appendChild(button);
Typescript 部分与 Java 非常相似,所以我理解这一点。现在我的问题是为什么在 JavaScript 中 Greeter
类嵌入到匿名中 function()
称呼?
为什么不这样写呢?
function Greeter(message) {
this.greeting = message;
}
Greeter.prototype.greet = function () {
return "Hello, " + this.greeting;
};
每种方法的优点/缺点是什么?
解决方案
以下称为 立即调用函数表达式:
(function(){ ... })();
它用于保持全局范围的干净。不过,在这种情况下没有必要,因为返回值已分配给变量 Greeter
. 。这种模式唯一有用的时候是当你想要“私有”时 静止的 成员。
例如。:
var Greeter = (function () {
var foo = 'foo', bar = 'bar'; /* only accessible from function's defined
in the local scope ... */
function Greeter(message) {
this.greeting = message;
}
Greeter.prototype.greet = function () {
return "Hello, " + this.greeting;
};
return Greeter;
})();
其他提示
这是为了允许私人成员。在此示例中,所有成员都是公共的,因此您的两个结构是等效的。但是,如果您想提供私有成员,您需要通过闭包将它们隐藏在调用范围之外。因此,如果您有一个像这样的私人成员:
class Greeter {
private greeting: string;
constructor (message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
你可能会得到这样的东西:
var Greeter = (function () {
var greeting="";
function Greeter(message) {
greeting = message;
}
Greeter.prototype.greet = function () {
return "Hello, " + greeting;
};
return Greeter;
})();
greeting 变量可用于匿名函数内定义的任何函数,但在其他地方不可见。
除了明显的范围/结束推理之外。使用立即调用自身的匿名函数来预加载(解释)类定义。这允许在执行中预先加载任何 JIT 优化。简而言之,对于更大更复杂的应用程序,它将提高性能。
匿名函数/自执行闭包通常用于封装作用域,以便只有返回值可以在其外部访问。(或附加到其他对象的任何东西,例如窗口)
匿名函数可能是为了防止与代码其他部分发生名称冲突。可以这样想,在匿名函数中,您甚至可以将一个名为“$”的变量声明为您想要的任何内容,同时在代码的其他部分使用 jQuery,而不会发生冲突。
闭包是调用带有参数的构造函数的唯一方法:
var w = new Greeter("hello")
还有其他方法,但都很复杂并且有局限性和缺点。