クラスのフィールドとメソッド

フィールド

クラス フィールドは、this 値のプロパティとして明示的に追加されるのではなく、クラスの本文内で直接宣言されます。ただし、結果は同じで、そのクラスのインスタンスでプロパティが定義されます。

class MyClass {
    myField;
}

const myClassInstance = new MyClass();

myClassInstance;
> MyClass { myField: undefined }

フィールドは値で初期化できます。これは多くの場合、クラス内のロジックで上書きできるデフォルト値です。

class MyClass {
    myResult = false;
    set setValue( myValue ) {
        this.myResult = myValue;
    }
}
const myClassInstance = new MyClass();

myClassInstance;
> Object { myResult: false }

myClassInstance.setValue = true;

myClassInstance;\
> Object { myResult: true }

クラス フィールドは、this を使用してクラスにアタッチされるプロパティと機能的に同じです。つまり、他のプロパティと同様に、クラス外からアクセスして変更できます。

class MyClass {
    myField = true;
}

const myClassInstance = new MyClass();

myClassInstance.myField;
> true

myClassInstance.myField = false;

myClassInstance.myField;
> false;

フィールドは、クラスのより高度な機能の基礎となります。

プライベート フィールドとメソッド

非公開のフィールドとメソッドは、クラス外からアクセスできません。プライベート プロパティはクラスのインスタンスに関連付けられます。つまり、各インスタンスには、クラスで定義されている独自のプライベート フィールドとメソッドのセットが含まれます。

プロパティをプライベートにするには、識別子を宣言する際に、識別子の先頭に # を追加します。

class MyClass {
    #myPrivateField = true;
    #myPrivateMethod() {}
}
const myClassInstance = new MyClass();

myClassInstance;
> MyClass { #myPrivateField: true }
    #myPrivateField: true
    <prototype>: Object { … }
        constructor: class MyClass {}
        <prototype>: Object { … }

プライベート フィールドは、それを含むクラスの本体で宣言する必要があります。後で this のプロパティとして値を変更できますが、this を使用してフィールドを作成することはできません。

スクリプトの別の場所から非公開フィールドにアクセスすることはできません。これにより、含まれる値を操作するために提供されているゲッター メソッドとセッター メソッドの外部でデータ プロパティが変更されることがなくなり、そのクラス内でのみ使用することを目的としたメソッドに直接アクセスできなくなります。

class MyClass {
    #myResult = false;
    set setValue( myValue ) {
        this.#myResult = myValue;
    }
}
const myClassInstance = new MyClass();

myClassInstance;
> MyClass { #myResult: false }

myClassInstance.#myResult = true;
> Uncaught SyntaxError: reference to undeclared private field or method #myResult

myClassInstance.setValue = true;

myClassInstance;\
> MyClass { #myResult: true }

ただし、ブラウザのデベロッパー コンソールは、デバッグ目的で非公開フィールドへのアクセスを許可するという点で、一貫性がないものの、一般的に制限が緩やかです。

class MyClass {
    #myPrivateField = true;
    #myPrivateMethod() {
        console.log( "This is inside a private method." );
    }
}
const myClassInstance = new MyClass();

myClassInstance;
> MyClass {#myPrivateField: true}

myClassInstance.#myPrivateField;
> true

myClassInstance.#myPrivateMethod();
> "This is inside a private method."
class MyClass {
    #myPrivateField = true;
    #myPrivateMethod() {
        console.log( "This is inside a private method." );
    }
}
const myClassInstance = new MyClass();

myClassInstance;
> MyClass {#myPrivateField: true}

myClassInstance.#myPrivateField;
> Uncaught SyntaxError: reference to undeclared private field or method #myPrivateField

myClassInstance.#myPrivateMethod();
> Uncaught SyntaxError: reference to undeclared private field or method #myPrivateMethod

プライベート フィールドのスコープは、それを含むクラスの本体に限定されます。つまり、子クラスでも、親クラスに関連付けられたプライベート フィールドにアクセスできません。

class MyClass {
    #myPrivateField = true;
}
class ChildClass extends MyClass {
    childMethod() {
        console.log( this.#myPrivateField );
    }
}
> Uncaught SyntaxError: reference to undeclared private field or method #myPrivateField

静的フィールドとメソッド

静的フィールドと静的メソッドは、そのクラスのインスタンスのメンバーではなく、クラス自体のメンバーです。このため、静的フィールドは、クラスの各インスタンスに一意ではないが、それらのインスタンスが参照する必要があるデータ(共有構成情報など)の中心点を提供します。静的メソッドは、多くの場合、インスタンスに含まれるフィールドに対してインスタンスの比較や並べ替えなど、クラスのインスタンスを操作するユーティリティ関数です。

クラスの本体で静的フィールドとメソッドを定義するには、static キーワードを使用します。

class MyClass {
    static myStaticField;
    static myStaticMethod() {}
}
const myClassInstance = new MyClass();

ドット表記を使用して静的メソッドを作成することもできます。

class MyClass {
    constructor() {}
}
MyClass.myStaticMethod = function() {}

静的プロパティにクラスのインスタンスからアクセスすることはできませんが、クラス コンストラクタでは使用できます。

class MyClass {
    static myStaticField = true;
    static myStaticMethod() {
        console.log( "A static method." );
    }
}
const myClassInstance = new MyClass();

myClassInstance.myStaticField;
> undefined

myClassInstance.myStaticMethod();
> Uncaught TypeError: myClassInstance.myStaticMethod is not a function

MyClass.myStaticField;
> true

MyClass.myStaticMethod();
> "A static method."

厳密には必須ではありませんが、クラスのインスタンスを操作するユーティリティを作成する場合は、静的メソッドを使用することをおすすめします。たとえば、クラスのインスタンスの並べ替えに特化した静的メソッドや、クラスのインスタンスを作成してそのクラス インスタンスを返すために必要な設定を含む静的ファクトリー メソッドなどがあります。

class User {
    constructor( name, email ) {
        this.name = name;
        this.email = email;
    }
    static fromObject( myObject ) {
        return new User( myObject.name, myObject.email ?? "Omitted" );
    }
}
const userObject = {
    "name" : "My Name",
    "email" : "my@email.address"
};
const secondUserObject = {
    "name" : "My Name"
};

const firstUser = User.fromObject( userObject );
const secondUser = User.fromObject( secondUserObject );

firstUser;
> Object { name: "My Name", email: "my@email.address" }

secondUser;
> Object { name: "My Name", email: "Omitted" }

理解度をチェックする

クラス内からのみアクセスできるフィールドのタイプは次のうちどれですか。

非公開フィールド
クラス フィールド
Static fields