今回はjsのプロトタイプとプロトタイプチェーンについて詳しく説明します。jsのプロトタイプとプロトタイプチェーンを使用する際の注意点は何ですか?実際のケースを見てみましょう。
作成するすべての関数にはプロトタイプ属性があり、この属性はプロトタイプ オブジェクトを指すポインターであり、このプロトタイプ オブジェクトが持つプロパティとメソッドはすべてのインスタンスで共有できます。
function Person(){ } Person.prototype.name = "Nicholas"; Person.prototype.age = 29; Person.prototype.sayName = function(){ alert(this.name); };var person1 = new Person(); person1.sayName(); //"Nicholas"var person2 = new Person(); person2.sayName(); //"Nicholas"alert(person1.sayName == person2.sayName); //true
1. プロトタイプ オブジェクトを理解する
新しい関数が作成されるたびに、特定のルール セットに従ってその関数のプロトタイプ プロパティが作成されます。このプロパティは、関数のプロトタイプ オブジェクトを指します。
デフォルトでは、すべてのプロトタイプ オブジェクトは、プロトタイプ属性が配置されている関数へのポインターを含むコンストラクター (constructor) 属性を自動的に取得します。
新しいインスタンスを作成するためにコンストラクターが呼び出されるとき、インスタンスにはコンストラクターのプロトタイプ オブジェクトを指すポインター (内部プロパティ) が含まれます。 ECMA-262 バージョン 5 では、このポインターを [[プロトタイプ]] と呼びます。
スクリプトで [[プロトタイプ]] にアクセスする標準的な方法はありませんが、Firefox、Safari、Chrome はすべてのオブジェクトでプロパティ proto をサポートしていますが、このプロパティはスクリプトにはまったく認識されません。
ただし、明確にしておくべき本当に重要な点は、この接続はインスタンスとコンストラクターの間ではなく、インスタンスとコンストラクターのプロトタイプ オブジェクトの間に存在するということです。
Person コンストラクターと Person.prototype を使用してインスタンスを作成する前述のコードを例として、図 6-1 に各オブジェクト間の関係を示します。
ここで、 person.prototype はプロトタイプ オブジェクトを指し、 Person.prototype.constructor は person を指します。 person1 と person2 には両方とも、person.prototype を指すだけの内部プロパティが含まれています。つまり、コンストラクターと直接の関係はありません。person1.sayName() を呼び出すことができます。これは、オブジェクトのプロパティを見つけるプロセスを通じて実現されます。 (最初にインスタンスを検索し、見つからない場合はプロトタイプの検索を続けます。)
alert(Person.prototype.isPrototypeOf(person1)); alert(Person.prototype.isPrototypeOf(person2));
2. より単純なプロトタイプ構文
前の例では、「人」と入力する必要があります。属性とメソッドを追加するたびにプロトタイプを作成します。不必要な入力を減らし、プロトタイプの機能をより視覚的にカプセル化するために、すべてのプロパティとメソッドを含むオブジェクト リテラルでプロトタイプ オブジェクト全体をオーバーライドすることが一般的です。function Person(){ } Person.prototype = { name : "Nicholas", age : 29, job: "Software Engineer", sayName : function () { alert(this.name); } };
1 つの例外があります: コンストラクター プロパティは person を指さなくなりました。
前述したように、関数が作成されるたびにそのプロトタイプオブジェクトも同時に作成され、このオブジェクトはコンストラクタープロパティも自動的に取得します。var friend = new Person(); alert(friend instanceof Object); //truealert(friend instanceof Person); //truealert(friend.constructor == Person); //falsealert(friend.constructor == Object); //true
operator を使用して Object と Person をテストすると、依然として true が返されますが、コンストラクターのプロパティは Object と等しく、Person と等しくありません。
コンストラクターの値が本当に重要な場合は、以下のように具体的に適切な値に戻すことができます。function Person(){ } Person.prototype = { constructor : Person, name : "Nicholas", age : 29, job: "Software Engineer", sayName : function () { alert(this.name); } };
3. ネイティブ オブジェクトのプロトタイプ
すべてのネイティブ参照型 (Object、Array、String など) には、コンストラクターのプロトタイプでメソッドが定義されています。 たとえば、sort() メソッドは Array.prototype にあり、substring() メソッドは String.prototype にあります。変更することは可能ですが、ネイティブ オブジェクトのプロトタイプを変更することはお勧めできません。4. プロトタイプ オブジェクトの問題
プロトタイプ パターン の最大の問題は、その共有の性質によって引き起こされます。 いずれかを変更すると、もう一方にも影響します。
function Person(){ } Person.prototype = { constructor: Person, name : "Nicholas", age : 29, job : "Software Engineer", friends : ["Shelby", "Court"], sayName : function () { alert(this.name); } };var person1 = new Person();var person2 = new Person();person1.friends.push("Van");alert(person1.friends); //"Shelby,Court,Van"alert(person2.friends); //"Shelby,Court,Van"alert(person1.friends === person2.friends); //true
五、原型链
其基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。然后层层递进,就构成了实例与原型的链条,这就是所谓原型链的基本概念。
function SuperType(){ this.property = true; } SuperType.prototype.getSuperValue = function(){ return this.property; };function SubType(){ this.subproperty = false; }//继承了 SuperTypeSubType.prototype = new SuperType();SubType.prototype.getSubValue = function (){ return this.subproperty; };var instance = new SubType(); alert(instance.getSuperValue()); //true
一张图说明:
property 则位于 SubType.prototype 中。这是因为 property 是一个实例属性,而 getSuperValue() 则是一个原型方法。既然 SubType.prototype 现在是 SuperType的实例,那么 property 当然就位于该实例中了。
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
以上がjsプロトタイプとプロトタイプチェーンの詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。