19

http://www.jibbering.com/faq/faq_notes/closures.htmlから:

注: ECMAScript は、内部オブジェクト型の内部 [[prototype]] プロパティを定義します。このプロパティはスクリプトで直接アクセスできませんが、プロパティ アクセサー解決で使用される内部 [[prototype]] プロパティで参照されるオブジェクトのチェーンです。オブジェクトのプロトタイプ チェーン。内部の [[prototype]] プロパティに関連付けられたプロトタイプの割り当て、定義、および操作を可能にするパブリック プロトタイプ プロパティが存在します。to two の関係の詳細は ECMA 262 (第 3 版) に記載されており、この説明の範囲を超えています。

二人の関係の詳細は?私はECMA 262を閲覧しましたが、そこで読んだのは次のようなものだけです:

コンストラクターに関連付けられたプロトタイプは、プログラム式の constructor.prototype によって参照できます。

ネイティブ ECMAScript オブジェクトには、[[Prototype]] と呼ばれる内部プロパティがあります。このプロパティの値は null またはオブジェクトであり、継承の実装に使用されます。

すべての組み込み関数とすべての組み込みコンストラクターには、式 Function.prototype の初期値である Function プロトタイプ オブジェクトがあります。

すべての組み込みプロトタイプ オブジェクトは、Object プロトタイプ オブジェクト自体を除いて、内部 [[Prototype]] プロパティの値として、式 Object.prototype (15.3.2.1) の初期値である Object プロトタイプ オブジェクトを持ちます。

このことから私が集めたのは、[[Prototype]] プロパティがprototypeほとんどすべてのオブジェクトのプロパティと同等であるということだけです。私は間違っていますか?

4

3 に答える 3

48

ほとんどの場合、あなたは正しいと思います。

すべてのオブジェクトには、[[Prototype]]継承に使用される隠しプロパティがあります。prototype関数にはさらに、関数がコンストラクターとして使用される場合にのみ使用されるパブリックプロパティがあります。オブジェクトがを使用して構築される場合、新しいオブジェクトのプロパティは、コンストラクターとして使用された関数のプロパティに設定されnewます。[[Prototype]]prototype

例えば

function C() {}
C.prototype = P1;  
var obj = new C();  // obj.[[Prototype]] is now P1.

[[Prototype]]プロパティは、を使用して取得できますObject.getPrototypeOf(<obj>)。(このメソッドはECMAScript 5で指定されています。古いバージョンのJavaScriptには、標準的な読み取り方法がありません[[Prototype]])。

通常、コンストラクターを介してプロトタイプにアクセスできます。例:

obj.constructor.prototype == Object.getPrototypeOf(obj) 

ただし、コンストラクター関数のプロトタイププロパティは再割り当てできますが[[Prototype]]、オブジェクトの作成後にオブジェクトのプロパティを再割り当てすることはできないため、これが常に当てはまるとは限りません。だからあなたがそうするなら:

C.prototype = P2;

それから

obj.constructor.prototype != Object.getPrototypeOf(obj)

のプロトタイプCは現在P2ですが[[Prototype]]、のobjはまだP1です。

プロパティを持つのは関数だけであることに注意してください。関数のプロパティは関数のプロパティと同じではないことにprototypeも注意してください!prototype[[Prototype]]

于 2008-12-20T11:46:58.273 に答える
12

質問に直接答えるには:論理的には、prototypeコンストラクターのプロパティのオブジェクトのプライベートコピーです。メタ言語を使用すると、次のようにオブジェクトが作成されます。

// not real JS

var Ctr = function(...){...};
Ctr.prototype = {...}; // some object with methods and properties

// the object creation sequence: var x = new Ctr(a, b, c);
var x = {};
x["[[prototype]]"] = Ctr.prototype;
var result = Ctr.call(x, a, b, c);
if(typeof result == "object"){ x = result; }
// our x is fully constructed and initialized at this point

この時点で、プロトタイプを変更できます。変更は、参照によってプロトタイプを参照するため、クラスのすべてのオブジェクトに反映されます。

Ctr.prototype.log = function(){ console.log("...logging..."); };

x.log();  // ...logging..

ただし、コンストラクターでプロトタイプを変更すると、作成済みのオブジェクトは引き続き古いオブジェクトを参照します。

Ctr.prototype = {life: 42};
// let's assume that the old prototype didn't define "life"

console.log(x.life);  // undefined
x.log();              // ...logging...

標準に完全に準拠すること[[prototype]]はできませんが、Mozillaは__proto__プロパティ(読み取り専用)を使用して標準を拡張し、通常は非表示になっています[[prototype]]

繰り返しますが、次のES3.1標準__proto__で合法化できます。

于 2008-12-20T17:00:57.077 に答える
4

olavk の回答に加えて: 一部の JavaScript 実装 (例: mozilla の) では、[[Prototype]] プロパティに直接アクセスできます...

于 2008-12-20T12:50:17.410 に答える