ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScriptのプロトタイプと継承を深く理解する_基礎知識

JavaScriptのプロトタイプと継承を深く理解する_基礎知識

WBOY
WBOYオリジナル
2016-05-16 17:37:07863ブラウズ

一般に、JavaScript のオブジェクトはプロトタイプへのポインターと、それ自身のプロパティのリストです。 JavaScript では、オブジェクトの作成時にコピーオンライトの概念が使用されます。
コンストラクターのみがプロトタイプ属性を持ちます。プロトタイプチェーンの継承は、コンストラクターのプロトタイプ属性を指す新しいポインターを作成します。
プロトタイプ属性が特別である理由は、JavaScript で属性を読み取るときのトラバーサル メカニズムによるものです。本質的には、これは単なる普通のポインタです。

コンストラクターには以下が含まれます:
1.Object
2.Function
3.Array
4.Date
5.String

いくつか例を挙げてみましょう

コードをコピーします コードは次のとおりです:

<script> <br>//各関数にはデフォルトの属性プロトタイプがあり、このプロトタイプのコンストラクターはデフォルトでこの関数を指します <br>//Person.constructor は Person と等しくないことに注意してください。 prototype.constructor。関数インスタンスにはコンストラクター属性が付属します。 this.name; <br> }; <br> var p = new Person("ZhangSan"); console.log( p.constructor === Person); // true、これは p 自体にコンストラクター属性が含まれていないため、ここで実際に呼び出されるのは Person.prototype.constructor <br></script>




私たちの目的は、

1 が Animal
から継承されていることを示します。2. p2 が Person
であることを示します。
パーソンがAnimalのプロトタイプ属性のメソッドを取得できるように、プロトタイプ属性のポインティングを変更しましょう。つまり、人は動物から継承します(人は獣です)



コードをコピーします

コードは次のとおりです。

<script> 関数 <a style="CURSOR: pointer" data="25504" class="copybut" id="copybut25504" onclick="doCopy('code25504')"> (名前) { <u> this.name = 名前; </u> }; </a> this.name を返す </span> }; new 人( "ZhangSan"); </div> <div class="codebody" id="code25504"> console.log(p.constructor === 人) // true <br> console.log(人.prototype.constructor === 人);本当です<br> <br> function Animal(){ } <br><br> person.prototype = new Animal(); // Person.prototype = Animal.prototype が使用されない理由は、new には他の関数があるためです。 <br> var p2 = new Person("ZhangSan"); <br><br>//(p2 -> Person.prototype -> Animal.prototype なので、p2.constructor は実際には Animal.prototype.constructor です)<br><br> console.log(p2.constructor === Person); // 出力は false ですが、本来の目的は、p2 が Person のインスタンスであることを示す true であることです。現時点では、目標 1 は達成されていますが、目標 2 は未達成です。 <br></script>




しかし、次のように変更すると


person.prototype = new Animal();
person.prototype.constructor = person; time p2. コンストラクターは正しく、person を指しており、p2 が person クラスのインスタンスであることを示していますが、新たな問題が発生します。現時点では、目標 2 は達成されていますが、目標 1 は未達成です。
目的 1 と目的 2 はこの時点で矛盾しています。プロトタイプはこの時点で 2 つの相反する意味を表現しているため、
1 は親クラスが誰であるかを示します。

2 は自身のインスタンスのプロトタイプとしてコピーされます。

したがって、prototype 属性を直接使用して親クラスが誰であるかを示すことはできませんが、親クラスが誰であるかを知るには getPrototypeOf() メソッドを使用します。



コードをコピー


コードは次のとおりです。


person.prototype = new Animal();

person.prototype.constructor = person;

var p2 = new Person("ZhangSan"); p2.constructor //関数 Person() を表示します。 🎜>Object.getPrototypeOf(person.prototype).constructor //関数を表示 Animal() {}

これら 2 つの概念を分離します


最後に要約します:
コード var p = new Person() が実行されると、new は次のことを行います:

空のオブジェクトを作成する

Person.prototype へのポインターを作成します

this キーワードを使用してこのオブジェクトをコンストラクターに渡し、コンストラクターを実行します。

Person.prototype = Animal.prototype を使用して person が Animal から継承していることを示す場合、instanceof メソッドは p も Animal のインスタンスであることを示し、true を返します。このメソッドが使用されない理由は次のとおりです。次の 2 つの理由:

1.new は新しいオブジェクトを作成します。これにより、 person.prototype.constructor = person を設定すると、Animal.prototype.constructor の値が person に変更されることを回避できますが、この新しく作成されたオブジェクトにコンストラクター インスタンス属性が動的に与えられます。そのため、インスタンスの属性コンストラクターは Animal.prototype.constructor をカバーし、 Person.prototype.constructor と Animal.prototype.constructor が分離されます。

2. 動物自身のこのオブジェクトの属性を人に渡すことはできません

hasOwnProperty() メソッドを使用すると、インスタンスのプロパティにアクセスするときとプロトタイプのプロパティにアクセスするときが明確になります。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。