17

TypeScriptと呼ばれる Microsoft の新しい JavaScript に似た言語について読んでいました。プレイグラウンド (サンプル セクション)には、JavaScript コードに変換された TypeScript 構文の単純なクラスがあります。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;
};

各方法の長所/短所は何ですか?

4

6 に答える 6

15

以下は、即時呼び出し関数式と呼ばれます。

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

グローバルスコープをクリーンに保つために使用されます。ただし、この場合は戻り値が variable に割り当てられるため、必要ありません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;
})();
于 2012-10-02T14:30:10.447 に答える
3

これは、プライベート メンバーを許可するためです。この例では、すべてのメンバーがパブリックであるため、2 つの構造は同等です。ただし、プライベート メンバーを提供する場合は、クロージャーを介して呼び出しスコープから非表示にする必要があります。したがって、次のようなプライベートメンバーがある場合:

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 変数は、無名関数内で定義されたすべての関数で使用できますが、それ以外の場所では見えません。

于 2012-10-02T14:36:14.053 に答える
3

明らかなスコープ/クロージャの推論に加えて。それ自体を呼び出す無名関数を使用すると、クラス定義がすぐにプリロード (解釈) されます。これにより、任意の JIT 最適化を実行内でフロント ロードできます。つまり、より大規模で複雑なアプリケーションの場合、パフォーマンスが向上します。

于 2012-10-02T14:44:19.133 に答える
2

無名関数/自己実行クロージャーは通常、スコープをカプセル化するために使用され、戻り値のみがスコープ外でアクセス可能になります。(または、ウィンドウなどの他のオブジェクトにアタッチするもの)

于 2012-10-02T14:31:01.710 に答える
1

無名関数はおそらく、コードの他の部分との名前の衝突を防ぐために存在します。このように考えてみてください。無名関数内で、"$" という変数を任意に宣言することもでき、同時にコードの他の部分で競合することなく jQuery を使用することもできます。

于 2012-10-02T14:31:08.120 に答える