6時だョ!!全員集合!!

Rails・JavaScrictを中心にアウトプットします。

2022年1月4日 JavaScript (JS Primer) クラスのインスタンス化

前提知識

クラスのインスタンス化の流れ

class MyClass {
}
// `MyClass`をインスタンス化する
const myClass = new MyClass();
// 毎回新しいインスタンス(オブジェクト)を作成する
const myClassAnother = new MyClass();
// それぞれのインスタンスは異なるオブジェクト
console.log(myClass === myClassAnother); // => false

クラスのインスタンスかどうかはinstanceof演算子で判定できます。

console.log(myClass instanceof MyClass); // => true
console.log(myClassAnother instanceof MyClass); // => true

クラスではインスタンスの初期化処理をコンストラクタ関数で行います。 コンストラクタ関数はnew演算子インスタンス化する際に自動的に呼び出されます。 コンストラクタ関数内でのthisはこれから新しく作るインスタンスオブジェクトとなります。

下のコード例では x座標とy座標の値を持つPointというクラスを定義し、 コンストラクタ関数(constructor)の中でインスタンスオブジェクト(this)のxとyプロパティに値を代入して初期化しています。

class Point {
    // コンストラクタ関数の仮引数として`x`と`y`を定義
    constructor(x, y) {
        // コンストラクタ関数における`this`はインスタンスを示すオブジェクト
        // インスタンスの`x`と`y`プロパティにそれぞれ値を設定する
        this.x = x;
        this.y = y;
    }
}

実際のコンストラクタ関数の定義

class Point {
    // 2. コンストラクタ関数の仮引数として`x`には`3`、`y`には`4`が渡る
    constructor(x, y) {
        // 3. インスタンス(`this`)の`x`と`y`プロパティにそれぞれ値を設定する
        this.x = x;
        this.y = y;
        // コンストラクタではreturn文は書かない
    }
}

// 1. コンストラクタを`new`演算子で引数とともに呼び出す
const point = new Point(3, 4);
// 4. `Point`のインスタンスである`point`の`x`と`y`プロパティには初期化された値が入る
console.log(point.x); // => 3
console.log(point.y); // => 4

ポイント

  • thisインスタンス変数を指します。(この挙動は今まで学んできたthisと違っているためこちらの素晴らしい記事を参考に勉強し納得しました)
  • コンストラクタ関数はnew演算子で引数と共に呼び出したときに実行されます。

関数とクラスの役割の違い

クラスは”インスタンスを初期化する場所”という関数とは違う役割のため、通常の関数として呼び出すことは出来ません

class MyClass {
    constructor() { }
}
// クラスのコンストラクタ関数として呼び出すことはできない
MyClass(); // => TypeError: class constructors must be invoked with |new|

エラー文を翻訳すると以下のように書いてありました。

  • TypeError: class constructors must be invoked with |new|
    (クラスコンストラクターは| new |で呼び出す必要があります)

インスタンスの返り値

コンストラクタは初期化処理を書く場所であるため、return文で値を返すべきではありません。

以下のコード例は非推奨の例になります。

Classにおいてnew演算子の評価結果はクラスのインスタンスであることが妥当ですが、以下の例ではreturn文でオブジェクトを返しています。

instanceofを実行してもpointはPointクラスのインスタンスとして評価されていないことがわかります。

// 非推奨の例: コンストラクタで値を返すべきではない
class Point {
    constructor(x, y) {
        // `this`の代わりにただのオブジェクトを返せる
        return { x, y };
    }
}

// `new`演算子の結果はコンストラクタ関数が返したただのオブジェクト
const point = new Point(3, 4);
console.log(point); // => { x: 3, y: 4 }
// Pointクラスのインスタンスではない
console.log(point instanceof Point); // => false

メモ

  • クラスはnew演算子インスタンス化して使うものです。
  • class構文で定義したクラスは関数として呼び出すことができません。
  • 関数として呼び出すと「クラスはnew演算子で呼び出す必要があります。」というエラーが出力されます。

クラス名は大文字ではじめる

クラス名は大文字ではじめる慣習があります。Railsのように必ず大文字にしないとエラーになるというわけではありませんが、変数名が被ったりしないようにできる事と、クラス名として明示的になるので大文字から書くことが推奨されています。

class Thing {}
const thing = new Thing();

参考

JS primer クラスのインスタンス化
Javascriptでオブジェクト指向するときに覚えておくべきこと JavaScriptのthisの覚え方

🎊祝!本日で投稿数が100記事になりました!🎊 f:id:morning_6:20220104093143p:plain