プロトタイプ継承は、JavaScriptにおいてオブジェクト間の継承を実現する仕組みです。あるオブジェクトが別のオブジェクトを参照し、プロトタイプのプロパティやメソッドを自動的に継承します。これにより、コードの再利用性や拡張性を高めることができます。
では詳しく見ていきましょう。
プロトタイプを例に例えると
プロトタイプを身近なものに例えると、料理のレシピや調理手順の書かれた本と似ています。レシピ本は、様々な料理を作る際の手順や材料の情報を提供します。これをプロトタイプと考えると、実際の料理はオブジェクトであり、レシピ本がそのプロトタイプです。
例えば、あなたが特定のレシピ本を持っていて、そのレシピ本にはチョコレートケーキの作り方が書かれています。新しいケーキを作るとき、そのケーキはチョコレートケーキのレシピ本を参照し、手順や材料を継承します。レシピ本には他のケーキのレシピも含まれているかもしれませんが、チョコレートケーキを作る場合には、そのレシピだけを参照します。
同様に、JavaScriptのオブジェクトもプロトタイプを参照し、プロトタイプのプロパティやメソッドを継承します。プロトタイプは共通の情報や機能を提供し、オブジェクトはそれを利用して特定の目的や動作を実現します。
プロトタイプとはなにか
プロトタイプは、JavaScriptにおいてオブジェクト間の継承を実現するための仕組みです。プロトタイプとは、あるオブジェクトが別のオブジェクトを参照するプロパティのことを指します。
オブジェクトはプロパティとメソッドを持っており、それらの定義はオブジェクト自体に直接格納されます。しかし、オブジェクトが持つプロパティやメソッドを見つけるために、JavaScriptはまずオブジェクト自身を調べます。もし見つからない場合、JavaScriptはオブジェクトのプロトタイプを調べ、そこからプロパティやメソッドを探します。このプロトタイプチェーンをたどって、最終的に目的のプロパティやメソッドを見つけることができるのです。
プロトタイプは、新しいオブジェクトを作成する際に役立ちます。新しいオブジェクトを作成するとき、それを作成したオブジェクトのプロトタイプを指定することができます。これにより、新しいオブジェクトはプロトタイプのプロパティやメソッドを自動的に継承します。
例えば、以下のようなコードを考えてみましょう:
// 親オブジェクト var parent = { name: "親", sayHello: function() { console.log("Hello, " + this.name); } }; // 子オブジェクト var child = Object.create(parent); child.name = "子"; child.sayHello(); // 出力: "Hello, 子"
この例では、parent
オブジェクトが親となり、child
オブジェクトがそのプロトタイプとして指定されています。child
オブジェクトはparent
オブジェクトのプロパティとメソッドを継承し、sayHello
メソッドを呼び出すことができます。
プロトタイプは、オブジェクトの階層構造を作成し、継承を実現するための重要な概念です。プロトタイプを活用することで、コードの再利用性や拡張性を高めることができます。初心者の方にとっては最初は少し難しく感じるかもしれませんが、プロトタイプの理解はJavaScriptの基礎を理解する上で重要なステップです。
プロトタイプの種類は?
JavaScriptにおいて、プロトタイプの種類は大きく分けて2つあります。
- オブジェクトのプロトタイプ(Object Prototype): すべてのオブジェクトは、オブジェクトのプロトタイプを持っています。これは、
Object.prototype
という特別なオブジェクトです。すべてのオブジェクトは、Object.prototype
を暗黙的に参照し、そのプロパティやメソッドを継承します。 - カスタムプロトタイプ(Custom Prototype): 開発者が独自に作成したオブジェクトや関数には、そのカスタムプロトタイプが存在します。これは、新しいオブジェクトを作成する際に継承元として指定されるオブジェクトです。カスタムプロトタイプは、
Object.prototype
を継承してさらに拡張することができます。
このように、オブジェクトのプロトタイプとカスタムプロトタイプの2つのプロトタイプがあります。それぞれのオブジェクトは、これらのプロトタイプを参照することで、継承やメソッドの呼び出し、プロパティのアクセスなどを行います。
Object Prototypeの中身は?
Object.prototype
は、すべてのJavaScriptオブジェクトが継承するプロトタイプオブジェクトです。以下に、Object.prototype
が持ついくつかの主要なプロパティとメソッドを示します:
constructor
:Object
コンストラクタ関数への参照です。すべてのJavaScriptオブジェクトは、このコンストラクタ関数によって作成されました。toString()
: オブジェクトを文字列に変換するためのメソッドです。デフォルトの実装では、オブジェクトの型名を返します。hasOwnProperty(propertyName)
: オブジェクト自身が指定したプロパティを持つかどうかを判定するメソッドです。isPrototypeOf(object)
: あるオブジェクトが別のオブジェクトのプロトタイプチェーン内にあるかどうかを判定するメソッドです。valueOf()
: オブジェクトをプリミティブな値に変換するためのメソッドです。通常、オブジェクト自体ではなく、オブジェクトが表す値を返します。
これらはいくつかの主要なプロパティとメソッドですが、Object.prototype
は他にもさまざまなプロパティやメソッドを持っています。JavaScriptのオブジェクトは、必要な場合にはObject.prototype
からこれらのプロパティやメソッドを継承し、利用することができます。
プロトタイプを継承している親のオブジェクトを変更する
プロトタイプを継承している親のオブジェクトを変更すると、それを継承している子のオブジェクトにも影響が及びます。
具体的には、子のオブジェクトは親のオブジェクトのプロパティやメソッドを継承しています。もし親のオブジェクトのプロパティやメソッドが変更されると、子のオブジェクトもそれを反映します。これは、プロトタイプベースの継承の仕組みによるものです。
例を見てみましょう:
// 親オブジェクトの定義 const parent = { property: 'value' }; // 子オブジェクトの作成 const child = Object.create(parent); console.log(child.property); // 出力: "value" // 親オブジェクトのプロパティの変更 parent.property = 'new value'; console.log(child.property); // 出力: "new value"
上記の例では、parent
オブジェクトを定義し、それを継承してchild
オブジェクトを作成しています。child
オブジェクトはparent
オブジェクトのプロパティを継承しており、child.property
としてアクセスすることができます。
その後、parent
オブジェクトのproperty
プロパティが変更されます。この変更は、child
オブジェクトにも反映され、child.property
を参照すると新しい値が表示されます。
このように、プロトタイプ継承では親のオブジェクトの変更が子のオブジェクトにも影響を与えます。プロトタイプチェーンを通じてプロパティやメソッドが参照されるため、親オブジェクトが変更されるとそれを継承している子オブジェクトも変更が反映される特性があります。
コンストラクタ関数とは
constructor function(コンストラクタ関数)は、JavaScriptにおいてオブジェクトを作成するための特別な関数です。コンストラクタ関数は、その名前が示すように、オブジェクトの初期化(構築)を担当します。
コンストラクタ関数は、通常大文字で始まる名前を持ち、new
キーワードを使って呼び出されます。コンストラクタ関数を呼び出すと、新しいオブジェクトが作成され、そのオブジェクトのthis
キーワードがコンストラクタ関数のインスタンスにバインドされます。また、コンストラクタ関数内では、this
を通じて新しいオブジェクトにプロパティやメソッドを追加することができます。
以下は、コンストラクタ関数の例です:
function Person(name, age) { this.name = name; this.age = age; } const john = new Person('John', 25); console.log(john.name); // 出力: "John" console.log(john.age); // 出力: 25
上記の例では、Person
というコンストラクタ関数が定義されています。このコンストラクタ関数は、name
とage
という引数を受け取り、新しいオブジェクトに対してそれぞれの値を設定します。
new
キーワードを使ってPerson
コンストラクタ関数を呼び出すと、新しいオブジェクトが作成されます。このオブジェクトはjohn
という変数に割り当てられ、name
プロパティとage
プロパティを持つようになります。
コンストラクタ関数は、同じ構造のオブジェクトを複数作成する際に便利です。また、コンストラクタ関数を使うことで、作成されたオブジェクトの状態を初期化することができます。
Property(プロパティ)とMethod(メソッド)
Property(プロパティ)とMethod(メソッド)は、オブジェクト指向プログラミングにおいて重要な概念です。以下にそれぞれの違いを詳しく説明します。
プロパティ(Property): プロパティは、オブジェクトが持つデータや値を表現します。オブジェクトの特徴や状態を示す変数のようなものです。プロパティは、オブジェクト内でキーと値のペアとして定義されます。プロパティには、数値、文字列、真偽値、関数、配列など、さまざまなデータ型の値を持つことができます。
例えば、以下のようなオブジェクトにおいて、name
とage
がプロパティです:
const person = { name: "John", age: 25 };
プロパティは、オブジェクトに関連付けられたデータを取得したり設定したりするために使用されます。プロパティへのアクセスは、ドット記法(object.property
)またはブラケット記法(object["property"]
)を使用して行われます。
メソッド(Method): メソッドは、オブジェクトに紐付いた関数のことを指します。メソッドは、オブジェクトが実行できる操作や機能を表現します。メソッドは、オブジェクト内で関数として定義されます。
例えば、以下のようなオブジェクトにおいて、greet
がメソッドです:
const person = { name: "John", age: 25, greet: function() { console.log("Hello, " + this.name + "!"); } };
メソッドは、オブジェクトに関連付けられた特定のアクションを実行します。他のプロパティやメソッドにアクセスするために、this
キーワードを使用することが一般的です。
メソッドは、オブジェクトの状態を変更するための処理や、オブジェクトが持つデータを操作するための処理などを行います。
プロパティとメソッドは、オブジェクト指向プログラミングにおいてオブジェクトの振る舞いや特性を表現するために使用されます。プロパティはデータを保持し、メソッドはそのデータに対する操作や処理を実行します。
プロトタイプ継承の方法
以下に、new
演算子、Object.create
メソッド、およびObject.setPrototypeOf
メソッドを使用したプロトタイプ継承の例と説明を示します。
1. new
演算子を使用したプロトタイプ継承:
function Parent(name) { this.name = name; } Parent.prototype.greet = function() { console.log('Hello, ' + this.name); }; function Child(name, age) { Parent.call(this, name); this.age = age; } Child.prototype = Object.create(Parent.prototype); Child.prototype.constructor = Child; const child = new Child('John', 10); child.greet(); // 出力: "Hello, John"
この例では、Parent
とChild
という2つの関数を定義しています。Parent
関数は親クラス(スーパークラス)を表し、Child
関数は子クラス(サブクラス)を表します。
Child
関数内で、Parent.call(this, name)
を使用して親クラスのコンストラクタを呼び出し、子クラスのインスタンスに親クラスのプロパティを設定します。その後、Child.prototype
をParent.prototype
を継承する新しいオブジェクトに置き換えます。これにより、Child
のインスタンスはParent
のメソッドを継承します。
2. Object.create
メソッドを使用したプロトタイプ継承:
const parent = { greet: function() { console.log('Hello, ' + this.name); } }; const child = Object.create(parent); child.name = 'John'; child.greet(); // 出力: "Hello, John"
この例では、parent
というオブジェクトを定義し、greet
というメソッドを持たせます。その後、Object.create
メソッドを使用してparent
オブジェクトを継承したchild
オブジェクトを作成します。
child
オブジェクトはparent
オブジェクトをプロトタイプとして持ち、name
プロパティを追加します。child
オブジェクトのgreet
メソッドは、parent
オブジェクトから継承されたメソッドを使用しています。
3. Object.setPrototypeOf
メソッドを使用したプロトタイプ継承:
const parent = { greet: function() { console.log('Hello, ' + this.name); } }; const child = { name: 'John' }; Object.setPrototypeOf(child, parent); child.greet(); // 出力: "Hello, John"
この例では、parent
というオブジェクトとchild
というオブジェクトを定義します。
今日はここまで!お疲れ様でした。