今回はJavaScriptのprototype
について調べてみました。
prototypeとは
prototype
とは何でしょうか。
MDNには下記の記載があります。
プロトタイプは、JavaScript オブジェクトが他のものから機能を継承する仕組みです。
継承がキーワードです。
prototype
はJavaScriptのすべてのオブジェクトが持つ特別なプロパティで、
オブジェクト間でプロパティやメソッドを共有するために使用されます。
特徴と例
prototype
は下記のような特徴を持ちます。
メモリ効率
メソッドをprototype
に定義すると、各インスタンスにメソッドを共有します。
各インスタンス毎に同じメソッドを複製するよりも、メモリの使用量を削減できます。
function User(name) {
this.name = name;
}
// prototypeにメソッドを定義
User.prototype.sayHello = function() {
console.log(`Hello, my name is ${this.name}`);
};
const user1 = new User("Alice");
const user2 = new User("Bob");
console.log(user1.sayHello === user2.sayHello); // true (共有されている)
動的な変更
プロトタイプは実行時に変更可能で、既存のオブジェクトにプロパティやメソッドを追加することができます。
function Car() {
this.wheels = 4;
}
// 後からメソッドを追加
Car.prototype.drive = function() {
console.log("The car is driving.");
};
const car1 = new Car();
car1.drive(); // The car is driving
プロトタイプチェーン
ブジェクトがプロパティやメソッドを探す際に、
オブジェクト自身のプロパティが見つからない場合、
そのオブジェクトのprototype
を順にたどって探索する仕組みであるプロトタイプチェーンがあります。
- オブジェクトのプロパティやメソッドを呼び出すとき、まずそのオブジェクト自身に該当するものがあるか探す
- 該当するものが見つからない場合、そのオブジェクトの
[[Prototype]]
(__proto__
) を辿り、次のレベルで探す - 全てのプロトタイプを辿っても見つからない場合、
undefined
が返される
下記の例では、child.name
はchild
自身に存在するため直接取得されます。
child.greet()
は child
に存在しないため、child
の __proto__
を辿り、parent.greet
を見つけて呼び出します。
// 親オブジェクトを作成
const parent = {
greet: function() {
console.log("Hello from parent!");
}
};
// 子オブジェクトを作成し、parentをプロトタイプとして設定
const child = Object.create(parent);
child.name = "Child";
// プロパティとメソッドを呼び出す
console.log(child.name); // Child(自分のプロパティ)
child.greet(); // Hello from parent!(プロトタイプから継承)
// プロトタイプチェーンの確認
console.log(child.__proto__ === parent); // true
おわりに
こんかいは概要だけ浚ってまとめました。
メモリを効率化が図れるので、
使えるタイミングでは積極的に採用していきたいです。
それでは。
参考文献