TypeScriptが出力するクラス定義コードを調べてみる

花粉がひどくて外を走る気力が湧きません…。やはり、ここはエアロバイク導入しかないですかね。

職場でJavaScriptのスタンダードなクラスの定義方法について話題になったので、 TypeScriptJavaScriptに変換した時にどんなクラス定義コードを出力しているか調べてみました。

TypeScriptのクラス定義コード

こちらが確認用のTypeScriptコードです。Animalクラスを定義して、そこからSnakeクラスを派生させています。

class Animal {
  name: string;

  Animal(name: string) {
    this.name = name;
  }
    
  move(meters: number): void {
    alert(this.name + "moved");
  }
}

class Snake extends Animal {
  move(): void {
    alert("hoge");
    super.move(5);
  }
}

出力されたJavaScriptコード

出力されたJavaScriptコードは以下のとおりです。

var __extends = this.__extends || function (d, b) {
  for (var p in b)
    if (b.hasOwnProperty(p)) d[p] = b[p];

  function __() {
    this.constructor = d;
  }
  __.prototype = b.prototype;
  d.prototype = new __();
};

var Animal = (function () {
  function Animal() {}

  Animal.prototype.Animal = function (name) {
    this.name = name;
  };

  Animal.prototype.move = function (meters) {
    alert(this.name + "moved");
  };

  return Animal;
})();

var Snake = (function (_super) {
  __extends(Snake, _super);

  function Snake() {
    _super.apply(this, arguments);
  }

  Snake.prototype.move = function () {
    alert("hoge");
    _super.prototype.move.call(this, 5);
  };

  return Snake;
})(Animal);

クラス間でプロパティをコピーする__extendsという関数を用意して、派生クラスの定義前に呼ぶ形式のようです。Processing.jsJavaクラスの機能を実現しようとしてすごいことになっていたことを考えると、機能と性能のバランス的に妥当なところなのではないかと思います。

その他のクラス定義コード

Processing.js(とjQuery)の作者であるJohn ResigSimple JavaScript Inheritanceというクラス定義手法をブログで紹介しています。こちらはTypeScriptの形式と比べると若干性能が落ちますが、よりエレガント書式でクラスを定義できます。