簡體   English   中英

為什么要在匿名函數()調用中嵌入JavaScript類?

[英]Why embed the JavaScript class in an anonymous function() call?

我正在閱讀微軟稱為TypeScript的類似JavaScript的新語言。 playground(示例部分)中 ,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;
};

每種方法的優點/缺點是什么?

以下稱為立即調用的函數表達式

(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 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM