10
var someObj = function() { }
var p = new someObj();

alert(someObj.prototype);   // This works
alert(p.prototype);         // UNDEFINED, but why?

someObj.prototype.model= "Nissan";
alert(p.model);             // This works! I understand the dynamic nature of prototypes, but doesn't that mean that p.prototype === someObj.prototype?

これはなぜですか?"p" は "someObj" のインスタンスなので、プロトタイプが未定義なのはなぜですか? つまり、「someObj」プロトタイプにプロパティを追加すると、「p」からアクセスできるのに、なぜプロトタイプにアクセスできないのでしょうか?

4

5 に答える 5

11

ここで重要なことはprototype、関数オブジェクトのプロパティはオブジェクトのプロトタイプではないということです。で作成したオブジェクトのプロトタイプとして割り当てられるオブジェクトですnew someObj。ES5 より前では、オブジェクトのプロトタイプに直接アクセスすることはできません。ES5 以降では、Object.getPrototypeOf.

alert(p.prototype); // UNDEFINED, but why?

その理由は、pオブジェクトに「prototype」というプロパティがないためです。基礎となるプロトタイプがありますが、それはアクセス方法ではありません。

すべての関数オブジェクトにはプロパティが呼び出されるprototypeため、それらがコンストラクタ関数として使用される場合、それらのコンストラクタによって作成されるオブジェクトの基礎となるプロトタイプのプロパティがどのようなものになるかを定義できます。これは役立つかもしれません:

function Foo() {
}
Foo.prototype.answer = 42;

console.log(Foo.prototype.answer); // "42"
var f = new Foo();
console.log(f.answer); // "42"

その最後の行は次のように機能します。

  1. オブジェクトを取得しfます。
  2. 「答え」と呼ばれる独自のfプロパティがありますか?
  3. いいえ、f試作品はありますか?
  4. はい、プロトタイプには「answer」という独自のプロパティがありますか?
  5. はい、そのプロパティの値を返します。

あなたはObject.createあなたの質問のタイトルに言及しました。Object.createコンストラクター関数とはまったく別のものであることを理解することが重要です。これが言語に追加されたので、コンストラクター関数を使用したくない場合は、その必要はありませんが、オブジェクトの作成時にオブジェクトのプロトタイプを直接設定できます。

于 2012-04-26T08:36:35.910 に答える
6

これprototypeは、それ自体のプロパティではなく、コンストラクタ関数のプロパティであるためです。ただし、オブジェクトにはコンストラクターへの参照があるため、そのプロパティを介してprototypeオブジェクトにアクセスできます。prototypeconstructor

function Foo() {}

Foo.prototype.foo = "bar";

var c = new Foo;

console.log( c.constructor === Foo );   // true
console.log( c.constructor.prototype ); // { foo: 'bar' }

prototypeただし、コンストラクター関数の初期プロパティを上書きすると、これは機能しません。

function Foo() {}

// I overwrite the prototype property, so I lose the initial reference
// to the constructor.
Foo.prototype = {
  foo: "bar"
};

var c = new Foo;

console.log( c.constructor === Foo );    // false
console.log( c.constructor === Object ); // true
console.log( c.constructor.prototype );  // {}

Object.getPrototypeOfそのため、ES5 で導入された新しい方法を使用する方がよいでしょう。

function Foo() {}

Foo.prototype = {
  foo: "bar"
};

var c = new Foo;

console.log( c.constructor === Foo );    // false
console.log( c.constructor === Object ); // true
console.log( c.constructor.prototype );  // {}
console.log( Object.getPrototypeOf(c) ); // { foo: 'bar' }

constructor別の解決策は、プロトタイプの参照を確実に復元することでした。

function Foo() {}

// Overwriting the initial prototype    
Foo.prototype = {
  constructor: Foo, // restore the constructor reference
  foo: "bar"
};
于 2012-04-26T08:44:36.350 に答える
2

この場合 p = someObj.prototype であるため、p.prototype は機能しません。

基本的に、 new 演算子を使用すると、コンストラクター someObj を使用して新しいオブジェクトが初期化されます。つまり、コンストラクターのプロトタイプのプロパティとメソッドを持つオブジェクトを返します。

したがって、p = someObj.prototype および p.prototype は、p がコンストラクターではないため未定義です。

この記事は、これについて詳しく説明するのに役立つかもしれません

http://www.htmlgoodies.com/html5/tutorials/javascript-prototyping-inheritance-explained.html#fbid=A2ikc3JLxeD

于 2012-04-26T08:37:38.633 に答える
1

pインスタンスですsomeObj。プロトタイプはコンストラクターに属します。pを使用して のコンストラクタ プロトタイプを取得できます。p.constructor.prototype

于 2012-04-26T08:37:59.840 に答える
0

Javascript では、コンストラクター、そして実際にはすべての関数がプロトタイプ プロパティを取得します。オブジェクト (つまり、一連のキーと値のペア) には、プロトタイプ プロパティがありません。上記の例では、

var someObj = function() { } // this is a function, so it has a prototype property
var p = new someObj(); // this is an instance object, so it doesn't

そのため、someObj.prototype は定義されていますが、p.prototype は定義されていません。

于 2012-04-26T08:47:39.827 に答える