TypeScriptに学ぶJavaScriptの書き方

posted in: JavaScript, TypeScript | 0

お久しぶりです。松山事務所の石丸です。
近頃実業務でも「Webの技術」でネイティブアプリを開発することが多くなってきました。
TypeScriptやES2015で少しでも保守性の高いコードを書きたいところですが、案件によってはES5.1で書かないといけないこともあります。
というわけで、今回はTypeScriptのコードをリアルタイムでJavaScriptにトランスパイルしてくれる
Playground · TypeScript を使って、
TypeScriptで書いていたアレをJavaScriptではどう書くのか、コードを比較しながら学んでいきたいと思います。

class

TypeScript

JavaScript

即時関数でクラスを定義するコードになりました。
protoypeにメソッドを実装するよくあるクラスの実装かと思います。
引数や戻り値の型情報、publicやprivateなどのアクセス修飾子は削除されています。
またconstもletもES5.1にはないのでvarになります。

interface

TypeScript

JavaScript

跡形もなく消えてなくなります。実行時には必要ないですしね。
interfaceとは関係ないのですが、Carクラスのコンストラクタを省略したため、デフォルトコンストラクタが生成されていました。

namespace

TypeScript

JavaScript

namespaceオブジェクトUtilityに対して、exportする変数、関数を追加することで外部に公開しています。
このときの即時関数の呼び出し方ですが、既にUtilityオブジェクトがある場合はそれを、なければ空のオブジェクトを作って渡しています。
こういう||を使った書き方はJavaScriptのイディオムらしいです。

継承

TypeScript

JavaScript

継承ついでに、親コンストラクタの呼び出し、メソッドのオーバーライドもしてみました。
__extends関数で難しそうに見えますが、これは親クラスのプロパティとプロトタイプをコピーする関数だと理解しました。
派生クラスは即時関数の引数で親クラスを_superとして受け取り、まずは__extends関数で継承を行います。
派生クラスから親クラスへのアクセスは_superを通し、メソッドはcallメソッドにthisを渡して呼び出します。

抽象クラスの継承

TypeScript

JavaScript

ほぼ継承と同じですが、抽象クラスのabstractメソッドが消えています。
interfaceと同様実行時には必要ないので、これは理解できるのですが、派生クラスのデフォルトコンストラクタの処理が理解できませんでした。
なぜ_superのnullチェックが必要なのか、なぜcallでなくapplyなのか、argumentsを渡す必要があるのか。
誰か教えて。

クラス変数、クラスメソッド

TypeScript

JavaScript

インスタンスを生成せずに使えるアレですが、namespaceと同じですね。

enum

TypeScript

JavaScript

列挙子の値指定の有無の両パターン書いてみました。
こちらもnamespaceと同じように、enumオブジェクトに対して列挙子を追加しています。
列挙子の値がないenum AnimalのJavaScriptで

のような呪文が出てきますが、次のようなコードと等価でした。

代入式の値は代入した値となるみたいです。
普段意識しませんが、a = b = 0a0 が代入されるのはそういうことですかね?

オプション引数とデフォルト引数

TypeScript

JavaScript

オプション引数であることは実行時には関係ないので削除されています。
デフォルト引数の方は、引数が省略されたか判定し、省略されていたらデフォルト値を代入。
といった普段手で書くのと同じなのですが、count === void 0がわかりませんでした。
MDN void 演算子によると、

void 演算子は与えられた式 (expression) を評価し、undefined を返します。

とのことでした。
undefinedはグローバル変数なので書き換えることが出来るらしく、ライブラリなどでは void 0 と書くらしいです。

アロー関数式

TypeScript

JavaScript

ES5.1にはないアロー関数式はfunctionに置き換わりますが、その関数内でthisを参照するかどうかによって
var _this = this;の1行が追加されます。賢いですね。
これで本物のアロー関数式と同様に外側のthisでbindされます。

まとめ

TypeScriptが出力するJavaScriptはきれいだと聞いていましたが、確かに読みやすかったかと思います。
ES5.1には足りない機能がたくさんあるのですが、それを実現するために見合わないコストをかけるより、
その言語なりの書き方で読みやすいコードを書いていきたいと思います。

JavaScriptプロの方からのツッコミ、アドバイスお待ちしております。

LINEで送る
Pocket