ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript オブジェクト指向プロトタイプ メモリ モデル

JavaScript オブジェクト指向プロトタイプ メモリ モデル

黄舟
黄舟オリジナル
2017-01-19 15:10:131232ブラウズ

JavaScript では、すべての関数にオブジェクトであるプロトタイプ属性があり、その機能は、特定の型のすべてのオブジェクト インスタンスがそれに含まれるプロパティとメソッドを共有できるようにすることです。

プロトタイプは JavaScript の非常に特別なオブジェクトです。関数が作成されると、この関数のコンストラクターを通じてプロトタイプ オブジェクトが生成されます。この特定のオブジェクトには、プロトタイプを指すプロパティがあります。 。

次のコードは、プロトタイプを使用して JavaScript オブジェクトを作成する方法を示しています。プロトタイプベースの作成を使用すると、プロパティとメソッドをオブジェクト Person 専用のプロパティとメソッドとして設定できるため、ウィンドウから呼び出すことができなくなり、オブジェクトのカプセル化要件を満たすことができます。

function Person(){};
 
Person.prototype.name = "Leon";
Person.prototype.age = 22;
Person.prototype.say = fucntion(){
  alert(this.name + "," + this.age);
}
 
var p1 = new Person();
p1.say();

プロトタイプのメモリモデル分析

プロトタイプメソッドを使用してクラスを作成する過程で、プロトタイプはメモリ内に 4 つの異なる状態を持ちます。プロトタイプのメモリ モデルを分析するために、引き続き Person クラスを作成する上記の例を使用します。コードは次のとおりです:

// 第一种状态
function Person(){};
 
// 第二种状态
Person.prototype.name = "Leon";
Person.prototype.age = 22;
Person.prototype.say = fucntion(){
  alert(this.name + "," + this.age);
}
 
// 第三种状态,创建了一个对象之后会有一个_proto_属性指向原型
// 在使用时如果对象内部没有找到该属性,就会去原型中查找
var p1 = new Person();
p1.say();
 
// 第四种状态
var p2 = new Person();
p2.name = "Ada";
p2.say();

まず、関数 Person(){}; を通じて person 関数を作成します。このとき、person 関数のプロトタイプのメモリ モデルは次のようになります。関数はメモリ内に配置されます。空間を割り当てます。この空間にはプロトタイプ属性があり、関数のプロトタイプ オブジェクトが作成されます。プロトタイプ オブジェクトにはコンストラクター属性があります。 Person 関数とそのプロトタイプ オブジェクトの関係を図に示します。このときのメモリモデルをプロトタイプの最初の状態と呼びます。

次に、プロトタイプを通じて Person 関数のプロパティとメソッドを設定します。これは、プロトタイプ メモリ モデルの 2 番目の状態です。 JavaScript オブジェクト指向プロトタイプ メモリ モデル

// 第一种状态
function Person(){};

上記のコードを追加した後のプロトタイプのメモリモデル構造は以下のようになります:

このとき、プロトタイプを通じて追加されたメソッドと属性はプロトタイプのメモリ空間に格納されます。

次に、Person クラスの作成が完了したら、new キーワードを使用して Person オブジェクトを作成できます。これは、プロトタイプ メモリ モデルの 3 番目の状態です。 JavaScript オブジェクト指向プロトタイプ メモリ モデル

// 第二种状态
Person.prototype.name = "Leon";
Person.prototype.age = 22;
Person.prototype.say = fucntion(){
  alert(this.name + "," + this.age);
}

プロトタイプのメモリ モデルの 3 番目の状態を次の図に示します。

new Person() によって Person オブジェクト p1 を作成します。このとき、p1 オブジェクトにはメモリ空間が割り当てられます。 p1 には、メモリ空間に _proto_ 内部プロパティがありますが、この内部プロパティも Person プロトタイプを指します。

_proto_ 内部属性は隠されていますが、 Person.prototype.isPrototypeOf(p1) メソッドを使用して、p1 に Person のプロトタイプを指す _proto_ があるかどうかを検出できます。 JavaScript オブジェクト指向プロトタイプ メモリ モデル

// 第三种状态
var p1 = new Person();
p1.say();

p1 オブジェクトの作成が完了した後、p1 オブジェクトを通じて Say() メソッドが呼び出されました。現時点では、p1 オブジェクトのメモリ空間には Say() メソッドは存在しません。 p1 のメモリ空間で Say() メソッドが見つからない場合、JavaScript は _proto_ 属性を通じて Preson のプロトタイプを検索し、それが見つかった後、対応する Say() メソッドが実行されます。

上記の 3 つの状態に加えて、プロトタイプのメモリ モデルには 4 番目の状態もあります。

別の Person オブジェクト p2 を作成し、p2 オブジェクトの name 属性を「Ada」に変更すると、プロトタイプ メモリ モデルの 4 番目の状態が表示されます。

console.info(Person.prototype.isPrototypeOf(p1));   // 控制台输出:true

上記のコードを呼び出した後のプロトタイプのメモリ モデルは以下のようになります:

オブジェクト p2 が作成されると、メモリ内にもそのためのスペースが割り当てられ、スペースには _ も表示されます。 p2 オブジェクトの proto_internal 属性は、person のプロトタイプを指します。

p2.name = "Ada"; を通じてオブジェクト p2 の name 属性に値を割り当てると、JavaScript は p2 のメモリ空間に独自の name 属性を設定し、その値を "Ada" に設定します。 JavaScript オブジェクト指向プロトタイプ メモリ モデル

次に、say() メソッドを呼び出します。このメソッドでは、まず p2 オブジェクト自体のメモリ空間に name 属性があるかどうかを検索します。検索は成功しました。それは Person プロトタイプには行きません。明らかに、この時点で p2 オブジェクトの空間には name 属性があるため、say() メソッドを呼び出して出力される名前は「Leon」ではなく「Ada」になります。

プロトタイプ内の値は置換されず、属性検索中にオブジェクト独自の空間内の同じ名前の属性によってのみ上書きされることに注意することが重要です。

上記はプロトタイプのメモリ モデルの 4 つの状態です。これらの 4 つの状態を理解することが、プロトタイプを習得するための鍵です。

上記は JavaScript オブジェクト指向プロトタイプ メモリ モデルの内容です。さらに関連する内容については、PHP 中国語 Web サイト (www.php.cn) をご覧ください。

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