typescript - Varför bädda in JavaScript-klassen i ett anonymt function() anrop?


Jag läste om det nya JavaScript-liknande språket från Microsoft som heter TypeScript. I lekplatsen (exempelsektionen) finns en enkel klass i TypeScript-syntax som har konverterats till JavaScript-kod. Eftersom jag kommer från en Java-programmeringsbakgrund var det intressant för mig att lära mig hur OOP görs i JavaScript när det kompileras från TypeScript.

TypeScript-koden:

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)

Och den motsvarande JavaScript-koden:

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-delen är väldigt lik Java, så det förstår jag. Nu är min fråga varför i JavaScript kroppen av Greeter-klassen är inbäddad i ett anonymt function()-anrop?

Varför inte skriva det så här?

function Greeter(message) {
    this.greeting = message;
}
Greeter.prototype.greet = function () {
    return "Hello, " + this.greeting;
};

Vilken är fördelen/nackdelen med varje metod?

Svar #1

Följande kallas en omedelbart anropad funktionsuttryck:

(function(){ ... })();

Det används för att hålla det globala omfånget rent. Dock är det i detta fall inte nödvändigt eftersom returvärdet tilldelas en variabel Greeter. Den enda gången detta mönster är användbart är när du vill ha "privata" statiska medlemmar.

Exempel:

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;
})();

Svar #2

Detta är för att tillåta privata medlemmar. I detta exempel är alla medlemmar offentliga, så dina två konstruktioner är ekvivalenta. Men om du vill tillhandahålla privata medlemmar behöver du dölja dem från den anropande scopen via en closure. Så om du har en privat medlem på följande sätt:

class Greeter {
    private greeting: string;
    constructor (message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
} 

Du skulle förmodligen få något liknande detta:

var Greeter = (function () {
    var greeting="";
    function Greeter(message) {
        greeting = message;
    }
    Greeter.prototype.greet = function () {
        return "Hello, " + greeting;
    };
    return Greeter;
})();

Hälsningsvariabeln kommer att vara tillgänglig för vilken funktion som helst som definieras inuti den anonyma funktionen, men osynlig överallt annars.

Relaterade artiklar