最近TSとJSについて学んだことを乱雑にまとめる

TS

インデックス型のオブジェクト

名称が定義されていないプロパティを持ったオブジェクトを作成することができる。

例えばkeyを文字列、valueが数値のプロパティを作成したい場合は [K: string]: number と記述する。 その場合は以下のようにプロパティを後から追加することができる。

let obj: {
  [K: number] : string;
};

obj = { a: 1, b: 2 };
obj.c = 3;
obj["d"] = 4;

JS

プロトタイプの作成方法

オブジェクトAを作成した後に const オブジェクトB = Object.create(オブジェクトA) とすると、Aを原型(プロトタイプ)とした新しいオブジェクトBを作成することができる。

例えば以下では、元とnameが異なるオブジェクトを作成している。

const button: { name: string } = { name: 'ボタン' };

const dangerousButton = Object.create(button);
dangerousButton.name = 'ぜっっったいに押すなよ!!!';

Rubyのような、クラスを元にして新しいオブジェクトを作成するクラスベース言語と比較して、こうした元々作成しているオブジェクトから、同じ構造・データ内容のさらに別のオブジェクトを作成する言語全般のことをプロトタイプベース言語と呼ぶ。

プロトタイプベースを私たちの普段の仕事で例えると、「前回使用した書類をひな形として今回必要な書類を作成すること」はかなり考え方として似通っているとのこと。

また継承はclassとextendsを用いての記法でも可能だが、このObject.createの記法でも実施可能である。

this

JavaScriptにおけるthisが何を指し示しているかは4パターンに分けられる。 以下の記事にてその4パターンについてまとめられていた。それをほんの少し改変したものを以下に書く。

Javascriptでオブジェクト指向するときに覚えておくべきこと - Qiita

(さらにその記事は以下の2記事の内容をまとめていた)

メソッド呼び出しパターン 何かに所属している時のthis
関数呼び出しパターン トップレベル(グローバルオブジェクト)のthis
コンストラクタ呼び出しパターン コンストラクタ内のthis
apply,call呼び出しパターン function#apply とか function#call とかで無理矢理変更した時のthis

関数内でthisを使用するとトップレベルを参照するが、strictモードがONになっているとトップレベルの情報ではなくundefinedが格納されてしまう。

この事象を防ぐためには呼び出す関数の記法としてアロー関数を使用すればよい。 アロー関数内でthisを使用すると、トップレベルではなく関数の外にあるオブジェクトのthis値を参照するため、結果的に意図していた通りにthisが機能してくれることとなる。

例えば以下のコードでは、doIt内のthisはその外にあるメソッドの、greetのthisを参照している。

そしてgreetのthisはと言うとその外にあるクラスの、Personを参照している。

そのためPersonのインスタンスであるcreamyにおいてgreetを実行すると、doIt => greet => creamyという流れでthisはcreamyを参照をして、結果ととしてcreamy.greet()を実行すると「Hi, I'm Mami」が出力される。

class Person {
  constructor(name) {
    this.name = name;
  }

  greet() {
    const doIt = () => {
      console.log(`Hi, I'm ${this.name}`);
      doIt();
    }
  }
}

const creamy = new Person('Mami');
creamy.greet();

Webpackとモジュールシステム

webpackがコードをバンドルする過程で、ES Modules(import・exportをJS内で利用するためのモジュールシステム)がコード全体に適用されるためにimport等が結果的に使用できるようになる。

加えてCreate React AppによってReactアプリを作成するとWebpackは勝手にインストールがされているので、開発者はimport等が使用可能な環境かどうかを気にせずに済む。

webpackなどのバンドラの存在意義として「ES Modulesをコードに適用させる」というのは1つ大きな点として挙げられるが、一方で普通に「js等の各ファイルの依存関係を解決して、1つにまとめる」という意義も依然として大きいため、ES Modulesがブラウザ・node等のJSの実行環境に元々から組み込まれるようになったとしても、バンドラはおそらく利用され続けるだろう、とのこと。

まとめていないまとめ

今の職場ではReactとTS使ってるからどちらもやらないとだけど、そのどちらともまずはJSを学ぶことが必要となるので、要は大変です・・・

参考リンク

りあクト! TypeScriptで始めるつらくないReact開発 第3.1版【Ⅰ. 言語・環境編】 - くるみ割り書房 ft. React - BOOTH