ホームページ >ウェブフロントエンド >jsチュートリアル >JavaScript プロトタイプとプロトタイプ チェーンを分析する

JavaScript プロトタイプとプロトタイプ チェーンを分析する

亚连
亚连オリジナル
2018-05-29 15:35:091729ブラウズ

この記事では、JavaScript プロトタイプとプロトタイプ チェーンの関連知識ポイントと使用方法の共有について詳しく説明します。興味のある方は参照してください。

作成するすべての関数にはプロトタイプ属性があり、この属性はプロトタイプ オブジェクトを指すポインターであり、このプロトタイプ オブジェクト内のプロパティとメソッドはすべてのインスタンスで共有できます。

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. プロトタイプ オブジェクトを理解する

新しい関数が作成されるたびに、特定のルール セットに従ってその関数のプロトタイプ プロパティが作成されます。このプロパティは、関数のプロトタイプ オブジェクトを指します。

デフォルトでは、すべてのプロトタイプ オブジェクトは、プロトタイプ属性が配置されている関数へのポインターを含むコンストラクター属性を自動的に取得します。

新しいインスタンスを作成するためにコンストラクターが呼び出されるとき、インスタンスにはコンストラクターのプロトタイプ オブジェクトを指すポインター (内部プロパティ) が含まれます。 ECMA-262 バージョン 5 では、このポインターを [[プロトタイプ]] と呼びます。

スクリプトで [[Prototype]] にアクセスする標準的な方法はありませんが、Firefox、Safari、Chrome は他の実装のすべてのオブジェクトで __proto__ 属性をサポートしていますが、この属性はスクリプトにはまったく表示されません。

ただし、明確にしておくべき本当に重要な点は、この接続はインスタンスとコンストラクターの間ではなく、インスタンスとコンストラクターのプロトタイプ オブジェクトの間に存在するということです。

Person コンストラクターと Person.prototype を使用してインスタンスを作成する前述のコードを例として、図 6-1 に各オブジェクト間の関係を示します。

ここで、 person.prototype はプロトタイプ オブジェクトを指し、 Person.prototype.constructor は person を指します。

person1 と person2 には両方とも、person.prototype を指すだけの内部プロパティが含まれています。つまり、コンストラクターと直接の関係はありません。

person1.sayName() を呼び出すことができます。これは、オブジェクトのプロパティを見つけるプロセスを通じて実現されます。 (最初にインスタンスを検索し、見つからない場合はプロトタイプの検索を続行します。)

用isPrototypeOf()方法判断实例与原型对象之间的关系
alert(Person.prototype.isPrototypeOf(person1)); //true
alert(Person.prototype.isPrototypeOf(person2)); //true
用Object.getPrototypeOf() 方法返回实例的原型对象
alert(Object.getPrototypeOf(person1) == Person.prototype); //true
使用 hasOwnProperty() 方法可以检测一个属性是存在于实例中,还是存在于原型中。
alert(person1.hasOwnProperty("name")); //false  来着原型
person1.name = "Greg";
alert(person1.name); //"Greg"——来自实例
alert(person1.hasOwnProperty("name")); //true

2. より単純なプロトタイプ構文

前の例では、「person.prototype」と入力する必要があります。属性とメソッドを追加するたびに。不必要な入力を減らし、プロトタイプの機能をより視覚的にカプセル化するために、すべてのプロパティとメソッドを含むオブジェクト リテラルでプロトタイプ オブジェクト全体をオーバーライドすることがより一般的です。

function Person(){
}
Person.prototype = {
  name : "Nicholas",
  age : 29,
  job: "Software Engineer",
  sayName : function () {
    alert(this.name);
  }
};

上記のコードでは、オブジェクト リテラルとして作成された新しいオブジェクトに person.prototype を設定しています。最終結果は同じですが、1 つの例外があります。コンストラクター プロパティは Person を指さなくなりました。

前述したように、関数が作成されるたびにそのプロトタイプオブジェクトも同時に作成され、このオブジェクトはコンストラクタープロパティも自動的に取得します。

var friend = new Person();
alert(friend instanceof Object); //true
alert(friend instanceof Person); //true
alert(friend.constructor == Person); //false
alert(friend.constructor == Object); //true

ここでは、instanceof 演算子を使用して 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

5. プロトタイプ チェーン

基本的な考え方は、プロトタイプを使用して、ある参照型に別の参照型のプロパティとメソッドを継承させることです。次に、層ごとに、インスタンスとプロトタイプのチェーンが形成されます。これが、いわゆるプロトタイプ チェーンの基本概念です。

function SuperType(){
  this.property = true;
}
SuperType.prototype.getSuperValue = function(){
  return this.property;
};
function SubType(){
  this.subproperty = false;
}
//继承了 SuperType
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function (){
  return this.subproperty;
};
var instance = new SubType();
alert(instance.getSuperValue()); //true

絵の説明:

以上、皆さんの参考になれば幸いです。

関連記事:

vueデータコントロールビューのソースコード分析

Reactの高次コンポーネントの簡単な説明

vue-cli axiosリクエストメソッドとクロスドメイン処理の問題

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

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