javascript - なぜTypeScriptはクラスを匿名関数でラップするのか?
例えば、Dog クラスを持ってみましょう:
class Dog {
static food;
private static static_var = 123;
constructor(private name) {}
speak() {
console.log(this.name + ', I eat ' + Dog.food + ', ' + Dog.static_var);
}
}
JSにコンパイル済み:
var Dog = (function () {
function Dog(name) {
this.name = name;
}
Dog.prototype.speak = function () {
console.log(this.name + ', I eat ' + Dog.food + ', ' + Dog.static_var);
};
Dog.static_var = 123;
return Dog;
})();
これは同じようにうまく機能し、より簡単です:
function Dog(name) {
this.name = name;
}
Dog.prototype.speak = function () {
console.log(this.name + ', I eat ' + Dog.food + ', ' + Dog.static_var);
};
Dog.static_var = 123;
匿名関数ラッパーを使用する理由には(「美学」以外に)何かありますか?
回答 #1
二つの主な違いはホイスティングに関係しています。
TypeScript はクラスを変数への関数式の代入にコンパイルします。つまり、結果として得られるコンストラクタは、代入の時点でのみ存在し始めます。それ以前に発生するコードでは、Dog は undefined にバインドされます。
一方で、あなたの実装ではホイスティングの影響を受ける通常の関数を使用しています――そのスコープ内の任意のコードは、関数の前に記述されているコードも含めて、Dog コンストラクタを呼び出すことができます。
TypeScriptは、クラスが実際に定義される前に存在しないことを確認することを好むようです。これは、おそらく同じスコープ内で複数のポイントでクラスを再定義できるようにするためでしょう。