ホームページ  >  記事  >  ウェブフロントエンド  >  JS プロトタイプ チェーンについて詳しく説明します。

JS プロトタイプ チェーンについて詳しく説明します。

不言
不言転載
2018-10-19 14:53:553132ブラウズ

この記事の内容は、JS プロトタイプ チェーンについて詳しく説明しています。必要な方は参考にしていただければ幸いです。

JS プロトタイプとプロトタイプ チェーンについての私の理解はいつも混乱していましたが、「JavaScript 高度なプログラミング」やさまざまな記事を読んだ後、ようやくプロトタイプとプロトタイプ チェーンについて予備的な理解ができました。深く理解するために、少し前に遭遇した質問を分析し、自分のアイデアを使用してそれを解釈し、プロトタイプとプロトタイプ チェーンについての理解を深めます。

1. 質問

次のプログラムを実行すると結果はどうなりますか?

function Animal() {
    this.name = 'Animal';
}

Animal.prototype.changeName = function (name) {
    this.name = name;
}

function Cat() {
    this.name = 'Cat';
}

var animal = new Animal();

Cat.prototype = animal;
Cat.prototype.constructor = Cat;

var cat = new Cat();

animal.changeName('Tiger');

console.log(cat.name)

A. 猫
C. トラ
D. 答えは
B 猫

2. 解釈

1. プロトタイプ オブジェクト新しい関数が作成されるたびに、このプロパティ ポイントに従ってその関数のプロトタイプ属性が作成されます。関数のプロトタイプ オブジェクトに。デフォルトでは、すべてのプロトタイプ オブジェクトは、プロトタイプ属性が配置されている関数へのポインターであるコンストラクター属性を自動的に取得します。

次の図は、
function Animal() {
    this.name = 'Animal';
}
Animal.prototype.changeName = function (name) {
    this.name = name;
}
を説明するために使用されます


JS プロトタイプ チェーンについて詳しく説明します。最初に、Animal 関数が作成され、Animal Prototype と Animal を指すプロトタイプ属性が含まれます。 .prototype コンストラクターは Animal を指します。このとき、name 属性は関数内で定義されているため、Animal Prototype にはなく、changeName 関数は Animal.prototype.changeName を通じて定義されているため、複数のオブジェクトをインスタンス化するときにこのメソッドを使用してプロトタイプを共有できます。保存方法。 同様に、Cat 関数を作成する場合も同様です。

function Cat() {
    this.name = 'Cat';
}


JS プロトタイプ チェーンについて詳しく説明します。2. インスタンスの作成

コンストラクターを呼び出して新しいインスタンスを作成すると、インスタンスにはポインターが含まれます。内部 (内部プロパティ)、コンストラクターのプロトタイプ オブジェクトを指します。このポインタは、ECMA-262 第 5 版では [[プロトタイプ]] と呼ばれています。スクリプトで [[Prototype]] にアクセスする標準的な方法はありませんが、Firefox、Safari、および Chrome はすべてのオブジェクトの属性 __proto__ をサポートしています。この接続は、インスタンスとコンストラクターの間ではなく、インスタンスとコンストラクターのプロトタイプ オブジェクトの間に存在することに注意することが重要です。

// 将Cat的原型对象指向animal实例,获得animal中的属性,原有的属性丢失
Cat.prototype = animal;
JS プロトタイプ チェーンについて詳しく説明します。

JS プロトタイプ チェーンについて詳しく説明します。この部分は、Cat のプロトタイプ オブジェクトのポインタを次のように指すのと同じです。そのため、Cat プロトタイプ オブジェクトの元のコンストラクター属性は失われ、name 属性と __proto__ 内部属性を含む、animal インスタンスの属性に置き換えられます。同時に、__proto__ 属性も Animal.prototype を指します。そのため、Cat は、Animal に呼び出されるプロパティとメソッドを検索するプロトタイプの Chain を渡すこともできます。

// 相当于重新创建了constructor,指向Cat构造函数
Cat.prototype.constructor = Cat;

JS プロトタイプ チェーンについて詳しく説明します。この部分は、プロトタイプ オブジェクトでコンストラクター属性を再作成し、Cat コンストラクターを指すことと同じです。

var cat = new Cat();   // 实例化一个Cat对象,跟实例化Animal相似

JS プロトタイプ チェーンについて詳しく説明します。3. メソッド

animal.changeName('Tiger');
を呼び出します。 var Animal = new Animal() が Animal オブジェクトをインスタンス化するとき、Animal には以下が含まれます。 Animal.prototype を指す内部プロパティ。つまり、animal はコンストラクター Animal と直接の関係がありません。ただし、changeName はインスタンスに含まれていませんが、animal.changeName(name) を呼び出すことができることがわかります。これは、オブジェクト属性を見つけるプロセス、つまり、

最初にインスタンスを見つけます。インスタンス内で、animalにchangeNameメソッドがあるかどうか、ない場合は検索を続け、Animal.prototypeに移動してchangeNameメソッドがあるかどうかを確認し、ある場合はそれを呼び出し、ない場合は検索を続け、Object内を検索します。プロトタイプの場合、最終的に見つからなかった場合は null が返されます。

明らかに、ここのインスタンスanimalにはchangeNameメソッドがないため、Animal.prototypeに移動してchangeNameメソッドを見つけ、それを呼び出してインスタンスanimalのname属性をTigerに正常に変更する必要があります。

このとき、Cat.prototype はインスタンスの Animal を指しているため、Cat.prototype の name 属性も Tiger に変更されます。

JS プロトタイプ チェーンについて詳しく説明します。

console.log(cat.name)  // Cat

最后,获取cat.name,与查找方法同样,也是先去实例中cat查找是否含有name属性,在这里很明显是存在的,因此直接结束寻找,此时cat.name = 'Cat'。

三、总结

通过这道题,加深了我对原型和原型链的理解,其实这道题也可以扩展到关于继承的知识点,在JavaScript中实现继承主要是依靠原型链来实现。

以上がJS プロトタイプ チェーンについて詳しく説明します。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。