10 Stimmen

Javascript-Prototyp durch Object.create()

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?

Warum ist das so? Da "p" eine Instanz von "someObj" ist, warum ist der Prototyp undefiniert? Wenn ich dem Prototyp von "someObj" eine Eigenschaft hinzufüge, kann "p" darauf zugreifen, warum also ist der Prototyp nicht zugänglich?

11voto

T.J. Crowder Punkte 948310

Wichtig ist dabei, dass die prototype Eigenschaft von Funktionsobjekten ist nicht den Prototyp eines Objekts. Es ist das Objekt, das als Prototyp eines Objekts zugewiesen wird, das Sie über new someObj . Vor ES5 war es nicht möglich, direkt auf den Prototyp eines Objekts zuzugreifen; ab ES5 können Sie dies über Object.getPrototypeOf .

Re

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

Der Grund dafür ist, dass die p Objekt hat keine Eigenschaft namens "Prototyp". Es hat einen zugrunde liegenden Prototyp, auf den Sie aber nicht zugreifen können.

Alle Funktionsobjekte haben eine Eigenschaft namens prototype so dass wir, wenn sie als Konstruktorfunktionen verwendet werden, definieren können, welche Eigenschaften der zugrunde liegende Prototyp der von diesen Konstruktoren erzeugten Objekte haben wird. Das kann hilfreich sein:

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

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

Diese letzte Zeile funktioniert so:

  1. Holen Sie sich die f Objekt.
  2. Hat f haben ihre eigene Eigenschaft namens "Antwort"?
  3. Nein, hat f einen Prototyp haben?
  4. Ja, hat der Prototyp seine eigene Eigenschaft namens "Antwort"?
  5. Ja, geben Sie den Wert dieser Eigenschaft zurück.

Sie haben erwähnt Object.create im Titel Ihrer Frage. Es ist wichtig zu verstehen, dass Object.create ist von den Konstruktorfunktionen völlig unabhängig. Sie wurde der Sprache hinzugefügt, damit Sie, wenn Sie es vorziehen, keine Konstruktorfunktionen zu verwenden, dies nicht tun müssen, aber dennoch den Prototyp eines Objekts festlegen können - direkt bei der Erstellung dieses Objekts.

6voto

Ionuț G. Stan Punkte 168218

Das liegt daran, dass prototype ist eine Eigenschaft der Konstruktorfunktion, nicht eine Eigenschaft des Konstruktors selbst. Allerdings ist die prototype Objekt hat einen Verweis auf den Konstruktor, so dass Sie auf den Konstruktor eines Objekts zugreifen können. prototype über seine constructor Eigentum:

function Foo() {}

Foo.prototype.foo = "bar";

var c = new Foo;

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

Dies funktioniert jedoch nicht, wenn Sie die ursprüngliche prototype Eigenschaft der Konstruktorfunktion:

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 );  // {}

Deshalb ist es besser, wenn Sie die neue Object.getPrototypeOf Methode, die in ES5 eingeführt wurde.

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' }

Eine andere Lösung wäre gewesen, sicherzustellen, dass Sie die constructor Referenz auf den Prototyp:

function Foo() {}

// Overwriting the initial prototype    
Foo.prototype = {
  constructor: Foo, // restore the constructor reference
  foo: "bar"
};

2voto

GillesC Punkte 10447

P.prototype funktioniert nicht, weil in diesem Fall p = someObj.prototype.

Wenn Sie den new-Operator verwenden, wird grundsätzlich der Konstruktor someObj verwendet, um ein neues Objekt zu initialisieren. Das heißt, es wird ein Objekt zurückgegeben, das die Eigenschaften und Methoden des Prototyps des Konstruktors hat.

Somit ist p = someObj.prototype und p.prototype ist undefiniert, da p kein Konstruktor ist.

Dieser Artikel könnte dies näher erläutern

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

1voto

KooiInc Punkte 111454

p es un Instanz de someObj . Der Prototyp gehört zum Konstruktor. Sie können abrufen p Konstruktor-Prototyp mit p.constructor.prototype

0voto

Yusuf X Punkte 14165

In Javascript erhalten Konstruktoren und eigentlich alle Funktionen eine Prototyp-Eigenschaft. Ein Objekt (d.h. ein Satz von Schlüssel-Wert-Paaren) hat keine Prototyp-Eigenschaft. In Ihrem Beispiel oben,

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

Aus diesem Grund ist someObj.prototype definiert, p.prototype jedoch nicht.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X