JavaScriptプロトタイプとプロトタイプチェーン

阐述

[プロトタイププロパティ]:
JavaScriptでは、各オブジェクトには、関数のプロトタイプオブジェクトを指すプロトタイププロパティがあります。

prototype 属性

JavaScriptでは、すべての関数に、関数のプロトタイプオブジェクトを指すプロトタイププロパティがあります。

ダイアグラムを使用して、コンストラクターとインスタンスのプロトタイプ間の関係を表してみましょう。
ここに画像の説明を挿入

例えば:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
<script>
function Person(age) {
    
    
    this.age = age       
}
Person.prototype.name = 'wgchen'

var person1 = new Person()
var person2 = new Person()

console.log(person1.name) //wgchen
console.log(person2.name)  //wgchen
</script>
</body>
</html>

ここに画像の説明を挿入
上記の例では、関数のプロトタイプはオブジェクトを指しており、このオブジェクトは、コンストラクターが呼び出されたときに作成されるインスタンスのプロトタイプ、つまりperson1とperson2のプロトタイプです。

プロトタイプの概念:
各javascriptオブジェクト(nullを除く)が作成されると、別のオブジェクトに関連付けられます。このオブジェクトはプロトタイプと呼ばれ、各オブジェクトはプロトタイプからプロパティを「継承」します。

__proto__

これは、すべてのオブジェクト(nullを除く)が持つプロパティであり、と呼ばれ__proto__、このプロパティはオブジェクトのプロトタイプを指します。

ここに画像の説明を挿入

function Person() {
    
    

}
var person = new Person();
console.log(person.__proto__ === Person.prototype); // true

ここに画像の説明を挿入

function Person() {
    
    

}
var person = new Person();
console.log(person);

ここに画像の説明を挿入
追加の手順:

ほとんどのブラウザは、プロトタイプにアクセスするためのこの非標準的な方法をサポートしていますが、Person.prototypeには存在せず、実際、Object.prototypeから取得されます。

ゲッター/セッターであるほどプロパティではありません。obj.__proto__ 使用すると、リターンとして理解できますObject.getPrototypeOf(obj)

constructor

各プロトタイプには、関連するコンストラクターを指すコンストラクタープロパティがあります。

function Person() {
    
    

}
console.log(Person===Person.prototype.constructor)  //true

したがって、関係図を再度更新します。
ここに画像の説明を挿入

function Person() {
    
    }

var person = new Person();

console.log(person.__proto__ == Person.prototype) // true
console.log(Person.prototype.constructor == Person) // true

// 顺便学习一个ES5的方法,可以获得对象的原型
console.log(Object.getPrototypeOf(person) === Person.prototype) // true

追加の手順:

function Person() {
    
    

}
var person = new Person();
console.log(person.constructor === Person); // true

実際、person.constructorを取得する場合、コンストラクタープロパティは直接存在しません。コンストラクタープロパティを読み取れない場合は、personのプロトタイプであるPerson.prototypeから読み取られます。これは、プロトタイプにこのプロパティが含まれている場合があります。 、 それで:

person.constructor === Person.prototype.constructor

实例与原型

インスタンスのプロパティを読み取るときに、インスタンスが見つからない場合は、オブジェクトに関連付けられているプロトタイプのプロパティを探します。見つからない場合は、プロトタイプのプロトタイプを見つけて、最上位レベルを見つけます。

function Person() {
    
    

}

Person.prototype.name = 'Kevin';

var person = new Person();

person.name = 'Daisy';
console.log(person.name) // Daisy

delete person.name;
console.log(person.name) // Kevin

この例では、name属性をインスタンスオブジェクトpersonに追加し、person.nameを出力すると、結果は当然デイジーになります。

しかし、personのname属性を削除してperson.nameを読み取ると、personオブジェクトにname属性が見つからない場合は、personのプロトタイプ、つまりperson.__proto__ Person.prototypeから検索されます。幸い、名前が見つかりました。プロパティ、結果はケビンです。

プロトタイプのプロトタイプ

先ほど、プロトタイプもオブジェクトだと言いましたが、オブジェクトなので、最も原始的な方法で作成できます。

var obj = new Object();
obj.name = 'Kevin'
console.log(obj.name) // Kevin

実際、プロトタイプオブジェクトはObjectコンストラクターによって生成されます。前のポイントと組み合わせて、__proto__インスタンスはコンストラクターのプロトタイプを指しているので、関係図を更新しましょう。
ここに画像の説明を挿入

プロトタイプチェーン

コンストラクター、プロトタイプ、およびインスタンス間の関係を簡単に確認します。
各コンストラクターにはプロトタイプオブジェクトがあり、プロトタイプオブジェクトにはコンストラクターへのポインターが含まれ、インスタンスにはプロトタイプオブジェクトへの内部ポインターが含まれます。

では、プロトタイプオブジェクトを別のタイプのインスタンスと等しくするとどうなるでしょうか。
明らかに、この時点でのプロトタイプオブジェクトには、別のプロトタイプへのポインターが含まれ、それに応じて、他のプロトタイプにも別のコンストラクターへのポインターが含まれます。

別のプロトタイプが別のタイプのインスタンスである場合、上記の関係は引き続き成立します。このようにして、インスタンスとプロトタイプのチェーンが形成されます。これがいわゆるプロトタイプチェーンの基本的な考え方です。-「JavaScriptAdvancedProgramming」から抜粋

実際、簡単に言えば、それは上記の4-5のプロセスです。

上記の5つに続いて、Object.prototypeのプロトタイプはどうですか?

console.log(Object.prototype.__proto__ === null) // true

nullは「オブジェクトがない」ことを意味します。つまり、そこに値があってはなりません。

したがってObject.prototype.__proto__、の値はnullであり、Object.prototypeには、実際に意味を表すプロトタイプがありません。

したがって、プロパティを検索するときに、Object.prototypeを見つけて検索を停止できます。

最後の関係図は、次のように更新することもできます。
ここに画像の説明を挿入
図内の相互接続されたプロトタイプのチェーン構造は、青い線であるプロトタイプチェーンです。

おすすめ

転載: blog.csdn.net/weiguang102/article/details/124096531