我正在阅读有关 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")

还有其他方法,但都很复杂并且有局限性和缺点。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top