◆ 目的
JavaScriptでコンストラクタを用意し、そこからオブジェクト(インスタンス)を作り、プロトタイプチェーンをたどる様子を模式図を使って理解する。
少々厄介なオブジェクト、プロトタイプの関連が目が覚めたように分かるはずである。
◆ サンプルコード
・Personコンストラクタ関数Person()の作成
コンストラクタ関数は共通の性質はふるまいをもったオブジェクトを作る型である。
他の言語で言うところのクラスのようなものは、JavaScriptではただの関数で定義できるということである。
new演算子とともに記述されることを想定してカスタムコンストラクタ関数を生成する際には、通常の関数との混同を避けるために関数の最初の文字を大文字にするのがよいだろう。
var Person = function(age, gender) {
this.age = age;
this.gender = gender;
this.getAge = function() {
return this.age;
};
this.getGender = function() {
return this.gender;
};
};
・プロトタイププロパティに新しいオブジェクトの設定
Person.prototype.birthday = 'yyyymmdd';
・オブジェクト(インスタンス)化
person = new Person(20, 'man')
コンストラクタ関数と言ってもただの関数のようなものなのだが、new演算子を使って呼ばれた場合にただの関数とは異にする特徴を示す。コンストラクタ関数はreturnがなくともよい。オブジェクトインスタンスを構築して返す。
JavaScriptではパラーメタに引数を渡さなくてもかまわない。引数が渡されなければその変数はUndefinedが設定される。
◆ 模式図
・サンプルコードの模式化
Function.prototype Object.prototypeへ
↑ ↑
プロトタイプチェーン(__proto__ 経由)
Person() Person.prototype
+---------------+ +----------------------+
| __proto__ | | __proto__ |
| prototype | | constructor |
| age | | birthday: 'yyyymmdd' |
| gender | | |
| getAge | | |
| getGender | | |
+---------------+ +----------------------+
インスタンス化 ↑
↓ プロトタイプチェーン
person
+----------------------+
| __proto__ * |
| age: 20 |
| gender : 'man' |
| getAge: - |
| getGender: - |
+----------------------+
*
自分自身に存在しないプロパティ・メソッドが呼び出されると、__proto__ ([[Prototype]])をめぐった先を参照する。
person.__proto__ === Person.prototype
つまり、参照である。では、prototypeプロパティとしてbirthdayを設定したが、これはクラス変数のように、newされたオブジェクトで共有されるのだろうか。
person1 = new Person(〜);
person2 = new Person(〜);
person1.birthday = 19910101
person2.birthday = 20010101
alert(person1.birthday) // ?
(参考)
https://www.matthieuveillon.com/class/