JavaScriptのprototype解説
JavaScriptの.prototype
について
JavaScriptにおいて、.prototype
はオブジェクトのプロトタイプチェーンを定義するための重要な要素です。プロトタイプチェーンは、オブジェクトが継承するプロパティやメソッドを決定する階層的な構造です。
.prototype
の役割
- 新しいオブジェクトの作成
オブジェクトコンストラクタは、新しいオブジェクトを作成し、そのプロトタイプをコンストラクタの.prototype
プロパティに設定します。これにより、新しいオブジェクトはコンストラクタの.prototype
に定義されたプロパティやメソッドを継承します。 - プロトタイプチェーンの形成
各オブジェクトは自身のプロトタイプを指す__proto__
プロパティを持ち、これによりプロトタイプチェーンが形成されます。オブジェクトがプロパティやメソッドにアクセスすると、そのオブジェクトのプロトタイプ、そのプロトタイプのプロトタイプ、と順に検索されます。 - プロパティやメソッドの継承
オブジェクトは自身のプロトタイプからプロパティやメソッドを継承できます。つまり、オブジェクトが直接持たないプロパティやメソッドにアクセスすると、そのプロトタイプが検索され、そこで見つかった場合は使用されます。
例
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.greet = function() {
console.log("Hello, my name is " + this.name);
};
const john = new Person("John ", 30);
john.greet(); // Output: Hello, my name is John
この例では、Person
コンストラクタの.prototype
にgreet
メソッドが定義されています。john
オブジェクトはPerson
コンストラクタを使用して作成されるため、john
のプロトタイプはPerson.prototype
になります。そのため、john.greet()
を実行すると、Person.prototype.greet
メソッドが呼び出され、"Hello, my name is John"が出力されます。
.prototype
を活用する利点
- 動的なプロパティ追加
JavaScriptは動的な言語であるため、実行時にプロトタイプに新しいプロパティやメソッドを追加することができます。これにより、柔軟なオブジェクトの設計が可能になります。 - コードの再利用性
プロトタイプチェーンを利用することで、共通のプロパティやメソッドを複数のオブジェクト間で共有することができ、コードの再利用性を向上させることができます。
プロトタイプチェーンの理解
function Person(name) {
this.name = name;
}
Person.prototype.greet = function() {
console.log("Hello, my name is " + this.name);
};
const john = new Person(" John");
const jane = new Person("Jane");
john.greet(); // Output: Hello, my name is John
jane.greet(); // Output: Hello, my name is Ja ne
このコードでは、Person
コンストラクタが定義され、その.prototype
にgreet
メソッドが追加されています。john
とjane
という2つのオブジェクトが作成され、どちらもPerson.prototype
をプロトタイプとして継承します。そのため、両方のオブジェクトでgreet
メソッドを呼び出すことができます。
function Employee(name, salary) {
this.name = name;
this.salary = salary;
}
Employee.prototype = Object.create(Person.prototype);
Employee.prototype.constructor = Employee;
const bob = new Employee("Bob", 50000);
bob.greet(); // Output: Hello, my name is Bob
console.log(bob.salary); // Output: 50000
このコードでは、Employee
コンストラクタが定義され、その.prototype
をPerson.prototype
から継承しています。これにより、Employee
オブジェクトはPerson
オブジェクトのプロパティやメソッドを継承することができます。bob
オブジェクトはEmployee
コンストラクタを使用して作成されるため、Person
のgreet
メソッドとEmployee
独自のsalary
プロパティを継承します。
Person.prototype.sayHello = function() {
console.log("Hi there!");
};
john.sayHello(); // Output: Hi there!
jane.sayHello(); // Output: Hi there!
このコードでは、Person.prototype
に新しいメソッドsayHello
を追加しています。この変更は、Person.prototype
をプロトタイプとして継承するすべてのオブジェクトに影響を与えます。そのため、john
とjane
オブジェクトでもsayHello
メソッドを呼び出すことができます。
クラスの利用
JavaScriptのES6以降では、クラス構文が導入されました。クラスは、オブジェクトのテンプレートであり、プロパティやメソッドの定義をカプセル化することができます。クラスを使用してオブジェクトを作成すると、そのオブジェクトはクラスのプロトタイプを継承します。
class Person {
constructor(name) {
this.name = name;
}
greet() {
console.log("Hello, my name is " + this.name);
}
}
const john = new Person("John");
john.greet(); // Output: Hello, my name is Joh n
このコードでは、Person
クラスが定義され、greet
メソッドが定義されています。john
オブジェクトはPerson
クラスを使用して作成され、クラスのプロトタイプを継承します。
オブジェクトリテラルの直接定義
シンプルなオブジェクトを作成する場合は、オブジェクトリテラルを使用することもできます。オブジェクトリテラルは、プロパティと値を直接定義する構文です。
const person = {
name: "John",
greet() {
console.log("Hello, my name is " + this.name);
}
};
person.greet(); // Output: Hello, my name is John
このコードでは、person
オブジェクトが直接定義され、name
プロパティとgreet
メソッドが定義されています。
どちらの方法を選ぶべきか
- シンプルなオブジェクト
シンプルなオブジェクトを作成する場合は、オブジェクトリテラルを使用して直接定義することもできます。これは簡潔で読みやすいコードになります。 - 複雑なオブジェクト
クラスは、複数のプロパティやメソッドを持つ複雑なオブジェクトを定義する際に便利です。クラスを使用することで、コードの構造化と再利用性を向上させることができます。
どちらの方法を使用するかは、プロジェクトの要件や開発者の好みによって異なります。クラスを使用する場合は、クラスの構文と継承の仕組みを理解する必要があります。一方、オブジェクトリテラルを使用する場合は、プロパティとメソッドの直接定義が可能です。
javascript dynamic-languages prototype-oriented