我正在阅读微软称为TypeScript的类似JavaScript的新语言。在playground (example section)中,TypeScript语法中有一个简单的类转换为JavaScript代码。来自Java编程背景,我很有兴趣了解如何在使用TypeScript编译的JavaScript中完成OOP。
TypeScript代码:
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;
};
每种方法的优点/缺点是什么?
答案 0 :(得分:15)
以下称为立即调用的函数表达式:
(function(){ ... })();
用于保持全局范围的清洁。但是,在这种情况下,由于返回值被赋值给变量Greeter
,因此没有必要。此模式唯一有用的时间是您需要“私有”静态成员。
<强> E.g:强>
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;
})();
答案 1 :(得分:3)
这是为了允许私人会员。在此示例中,所有成员都是公共的,因此您的两个构造是等效的。但是,如果要为私有成员提供,则需要通过闭包将它们隐藏在调用范围内。因此,如果您有这样的私人会员:
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变量可用于匿名函数内定义的任何函数,但在其他任何地方都不可见。
答案 2 :(得分:3)
除了明显的范围/结束推理。使用调用自身的匿名函数会立即预加载(解释)类定义。这允许在执行中预先加载任何JIT优化。简而言之,对于更大的更复杂的应用程序,它将提高性能。
答案 3 :(得分:2)
匿名函数/自执行闭包通常用于封装作用域,以便只能在其外部访问返回的值。 (或任何附加到其他对象的东西,如窗口)
答案 4 :(得分:1)
匿名函数可能会阻止名称与代码的其他部分进行匹配。可以这样想,在你的匿名函数中,你甚至可以将一个名为“$”的变量声明为你想要的任何东西,同时在你的代码的其他部分使用jQuery而不会发生冲突。
答案 5 :(得分:-4)
闭包是用参数调用构造函数的唯一方法:
var w = new Greeter("hello")
还有其他方法,但都很复杂,有局限性和缺点。