1. プロトタイプ
関数のプロトタイププロパティ
- 各関数にはプロトタイプ属性があり、デフォルトでは Object の空のオブジェクト (つまり、プロトタイプ オブジェクト) になります。
- プロトタイプ オブジェクトには、関数オブジェクトを指す属性コンストラクターがあります。
パーソンのプロトタイプはそのパーソン・プロトタイプを指し、パーソン・プロトタイプのコンストラクターはパーソンを指します。
// 用户对象
function Person() {
};
console.log(Person.prototype);
Person.prototype.getMoney = function() {
return 5000000;
console.log("身价500w");
}
console.log((new Person()).getMoney());
プロトタイプオブジェクトにプロパティ (通常はメソッド) を追加する
- 関数: 関数のすべてのインスタンス オブジェクトは、プロトタイプ内のプロパティ (メソッド) を自動的に持ちます。
2. 明示的および暗黙的なプロトタイプ
各関数関数にはプロトタイプ、つまり明示的なプロトタイプ (プロパティ) があります。
すべてのインスタンス オブジェクトには、暗黙的なプロトタイプ (プロパティ) と呼ばれる __proto__ があります。
オブジェクトの暗黙的プロトタイプの値は、対応するコンストラクターの明示的プロトタイプの値です。
記憶構造
// 第1步,内部语句:this.prototype = {}
function Fn() {
};
console.log(Fn.prototype);
// 第2步,内部语句:this.__proto__ = Fn.prototype
let fn = new Fn();
console.log(fn.__proto__);
console.log(fn.__proto__ === Fn.prototype);
// 在原型上添加方法
Fn.prototype.test = function () {
console.log("invoke test...");
}
fn.test();
上記のコードに対応するメモリ構造は次のとおりです。
要約:
- 関数のプロトタイプ属性: 関数が定義されるときに自動的に追加され、デフォルト値は空の Object オブジェクトです。
- オブジェクトの __proto__ 属性: オブジェクトの作成時に自動的に追加され、デフォルト値はコンストラクターのプロトタイプ属性の値です。
- 明示的なプロトタイプはプログラム内で直接操作できますが、暗黙的なプロトタイプは直接操作できません (ES6 以前)
3. プロトタイプチェーン
3.1 アクセスシーケンス
プロトタイプ チェーン (暗黙的プロトタイプ チェーン) は、主にオブジェクトのプロパティ (メソッド) を見つけるために使用されます。オブジェクトのプロパティにアクセスする場合、
- まず独自の属性を検索し、見つかった場合は返します。
- そうでない場合は、__proto__ チェーンに沿って検索し、見つけて返します。
- 最終的に見つからなかった場合はunknownを返します
console.log(Object.prototype.__proto__)
function Fn() {
this.test1 = function() {
console.log("test1()")
}
}
Fn.prototype.test2 = function() {
console.log("test2()")
}
let fn = new Fn();
fn.test1();
fn.test2();
console.log(fn.toString);
fn.test3();
出力は次のとおりです。
コンストラクター/プロトタイプ/エンティティ オブジェクトの関係
関数の明示的なプロトタイプが指すオブジェクトは、デフォルトでは空の Object インスタンス オブジェクトです (ただし、Object は満たされていません)。
すべての関数は Function のインスタンスです (Function を含む)
オブジェクトのプロトタイプ オブジェクトは、プロトタイプ チェーンの終端です。
プロトタイプチェーンのプロパティの問題
オブジェクトのプロパティ値を読み取る場合: プロトタイプチェーン内で自動的に検索されます
オブジェクトのプロパティ値を設定する場合: プロトタイプチェーン内で検索されません。現在のオブジェクトにこのプロパティを直接追加し、その値を設定する
メソッド。通常はプロトタイプで定義され、属性は通常、コンストラクターを通じてオブジェクト自体に定義されます。
function Fn() {
}
Fn.prototype.a = 'xxx';
let fn1 = new Fn();
console.log(fn1.a, fn1);
let fn2 = new Fn();
fn2.a = 'yyy';
console.log(fn1.a, fn2.a, fn1)
出力は次のとおりです。
4. インスタンス
4.1 判断方法
式: A instanceof B B 関数
の明示的なプロトタイプ オブジェクトが A オブジェクトのプロトタイプ チェーン上にある場合は true を返し、それ以外の場合は false を返します。
関数は、新しい関数を通じてそれ自体で生成されるインスタンスです。
function Foo() {
}
let f1 = new Foo()
console.log(f1 instanceof Foo) // true
console.log(f1 instanceof Object) // true
完全なプロトタイプ関係図: