概要:このチュートリアルでは、JavaScriptクラスとその効果的な使用方法について学習します。
JavaScriptクラスは、オブジェクトを作成するための設計図です。クラスは、データをカプセル化し、データを操作する関数を含みます。
JavaやC#などの他のプログラミング言語とは異なり、JavaScriptクラスはプロトタイプ継承をより簡潔に記述するための糖衣構文です。つまり、ES6クラスは特別な関数です。
ES6以前のクラスを再検討
ES6以前は、JavaScriptにはクラスの概念がありませんでした。クラスを模倣するために、次の例に示すように、コンストラクター/プロトタイプパターンがよく使用されていました。
function Person(name) {
this.name = name;
}
Person.prototype.getName = function () {
return this.name;
};
var john = new Person("John Doe");
console.log(john.getName());
Code language: JavaScript (javascript)
出力
John Doe
仕組み
まず、name
という名前のプロパティを持つコンストラクター関数としてPerson
を作成します。 getName()
関数は、Person
型のすべてのインスタンスで共有できるように、prototype
に割り当てられます。
次に、new
演算子を使用して、Person
型の新しいインスタンスを作成します。そのため、john
オブジェクトは、プロトタイプ継承を通じて、Person
とObject
のインスタンスになります。
次のステートメントは、instanceof
演算子を使用して、john
がPerson
型とObject
型のインスタンスであるかどうかを確認します。
console.log(john instanceof Person); // true
console.log(john instanceof Object); // true
Code language: JavaScript (javascript)
ES6クラス宣言
ES6では、この例に示すように、クラスを宣言するための新しい構文が導入されました。
class Person {
constructor(name) {
this.name = name;
}
getName() {
return this.name;
}
}
Code language: JavaScript (javascript)
このPerson
クラスは、前の例のPerson
型のように動作します。ただし、コンストラクター/プロトタイプパターンの代わりに、class
キーワードを使用します。
Person
クラスでは、constructor()
はインスタンスのプロパティを初期化できる場所です。クラスのオブジェクトをインスタンス化すると、JavaScriptは自動的にconstructor()
メソッドを呼び出します。
以下は、Person
クラスのconstructor()
を自動的に呼び出す、新しいPerson
オブジェクトを作成します。
let john = new Person("John Doe");
Code language: JavaScript (javascript)
getName()
は、Person
クラスのメソッドと呼ばれます。コンストラクター関数と同様に、次の構文を使用してクラスのメソッドを呼び出すことができます。
objectName.methodName(args)
Code language: CSS (css)
例えば
let name = john.getName();
console.log(name); // "John Doe"
Code language: JavaScript (javascript)
クラスが特別な関数であることを確認するために、typeof
演算子を使用してPerson
クラスの型を確認できます。
console.log(typeof Person); // function
Code language: JavaScript (javascript)
予想どおり、function
が返されます。
john
オブジェクトは、Person
型とObject
型のインスタンスでもあります。
console.log(john instanceof Person); // true
console.log(john instanceof Object); // true
Code language: JavaScript (javascript)
クラスとカスタム型
コンストラクター関数で定義されたクラスとカスタム型の間には類似点がありますが、いくつかの重要な違いがあります。
まず、クラス宣言は、関数宣言のようにホイスティングされません。
たとえば、次のコードをPerson
クラス宣言セクションの上に配置すると、ReferenceError
が発生します。
let john = new Person("John Doe");
Code language: JavaScript (javascript)
エラー
Uncaught ReferenceError: Person is not defined
Code language: JavaScript (javascript)
次に、クラス内のすべてのコードは、自動的に厳密モードで実行されます。そして、この動作を変更することはできません。
3つ目に、クラスメソッドは列挙不可です。コンストラクター/プロトタイプパターンを使用する場合、プロパティを列挙不可にするためにObject.defineProperty()
メソッドを使用する必要があります。
最後に、次の例に示すように、new
演算子なしでクラスコンストラクターを呼び出すと、エラーが発生します。
let john = Person("John Doe");
Code language: JavaScript (javascript)
エラー
Uncaught TypeError: Class constructor Person cannot be invoked without 'new'
Code language: JavaScript (javascript)
new
演算子なしでコンストラクター関数を呼び出すことは可能です。この場合、コンストラクター関数は通常の関数のように動作します。
まとめ
- 新しいクラスを宣言するには、JavaScriptの
class
キーワードを使用します。 class
宣言は、プロトタイプ継承を拡張した糖衣構文です。