2013-05-21 14 views
13

Welchen Parameter sollte ich für das erste Elternobjekt übergeben, von dem andere erben und welches effizienter istUnterschied zwischen Object.create (Object.prototype), Object.create (Object) und Object.create (null)

Object.create(Object.prototype) 

Object.create(Object) 

Object.create(null) 

Object.create(null) gibt ein leeres Objekt

Object.create(Object) eine Funktion gibt, warum ???? (ich log geprüft, und es sagt Funktion ... i console.dir verwendet())

Object.create(Object) liefert ein nicht leeres Objekt

Wie funktioniert das Ganze Arbeit ... ich mehr an den Klassennamen .prototype Sache bin :(

Kann nicht verstehen, was hier los ist,

+0

Welcher gibt eine 'Funktion' zurück? Sie haben 'Object.create (Object)' zweimal aufgelistet und alle drei Varianten geben ein Objekt an mich zurück. –

+0

Oh, in Chrome 'Object.create (Object)' gibt eine 'Funktion', ich sehe. Scheint fehlerhaftes Verhalten aufgrund der Übergabe eines Konstruktors anstelle eines einfachen Objekts, das als Prototyp verwendet werden soll. –

+0

Woah, das ist durcheinander. 'var a = Object.create (Objekt); ein Anruf; // Funktionsaufruf() {[nativer Code]}; ein(); // TypeError: Objekt ist keine Funktion' – phenomnomnominal

Antwort

19

Vorwort: JavaScript verwendet prototypische Vererbung, die bedeutet, dass ein Objekt einen Prototyp haben kann (normalerweise hat), der ein anderes Objekt ist. Wenn Sie versuchen, den Wert einer Eigenschaft von einem Objekt abzurufen, das nicht vorhanden ist, sucht die JavaScript-Engine nach dem Prototyp des Objekts (und seinem Prototyp usw.), um es zu finden.

Object.create erstellt Objekte. Das erste Argument, das Sie Object.create geben, ist das Objekt, das als Prototyp des erstellten Objekts verwendet wird. Also:

// Create an object with a property 'foo' 
var a = { 
    foo: 42 
}; 

// Create a blank object using `a` as its prototype 
var b = Object.create(a); 

// Give `b` a property of its own 
b.bar = "hi"; 

der uns diese im Speicher gibt:

 
          +---------------+  +-------------------+ 
          | [[Prototype]] |----->| (the standard  | 
a----------------------+-->| foo: 42  |  | object prototype) | 
         | +---------------+  +-------------------+ 
         | 
    +---------------+ | 
b-->| [[Prototype]] |--+ 
    | bar: "hi"  | 
    +---------------+ 

Proof b verwendet a:

console.log(b.foo); // 42 
a.foo = 67; 
console.log(b.foo); // 67 

einige Ihrer Variationen Adressierung:

var o = Object.create(Object.prototype); 

That 's sinnlos, einfach var o = {}; verwenden, tut es das gleiche (erstellt ein neues leeres Objekt, dessen Prototyp ist Object.prototype).

var o = Object.create(Object); 

Erzeugt ein neues leeres Objekt o dessen Prototyp ist die Object Funktion. Es erstellt keine Funktion, nur ein Nichtfunktionsobjekt, das eine Funktion als Prototyp hat. Das wäre ziemlich merkwürdig und wahrscheinlich nicht das, was du willst.

var o = Object.create(null); 

Erstellt ein neues leeres Objekt o dessen Prototyp ist null. Da sein Prototyp null ist, hat er nicht die üblichen Object.prototype Sachen, wie toString und valueOf und hasOwnProperty. Das ist ein wenig ungewöhnlich, obwohl es Anwendungsfälle dafür gibt, etwa wenn Sie ein Objekt als Dictionary/Map verwenden und keine falschen Positiven für diese Eigenschaftsnamen wollen. (In ES2015 [aka ES6] ist eine andere Option stattdessen Map zu verwenden.

)

Wie thg435 unten in einem Kommentar weist darauf hin, einer der verwirrenden Dinge über JavaScript ist, dass der Prototyp eines Objekts ist eine ganz andere Sache, von der prototype Eigenschaft, die Sie auf Funktionen zu sehen. Es wäre wahrscheinlich besser, wenn die prototype Eigenschaft einen anderen Namen gehabt hätte (obwohl ich mir nicht vorstellen kann, welcher Name es wäre, ohne massiv klobig zu sein).

Ein Objekt (nennen wir es o) hat ein Prototyp-Objekt, von dem es Eigenschaften übernimmt. Das Objekt auf der prototype Eigenschaft von Funktionen ist nicht unbedingt der Prototyp eines Objekts überhaupt. Stattdessen wird das Objekt als Prototyp eines Objekts zugewiesen, das über new mit dieser Funktion erstellt wurde.

Beispiele helfen hier.

function Foo() { 
} 

diese Funktion hat Foo, eine Eigenschaft Foo.prototype, die auf ein Objekt bezieht. Dieses Objekt wird noch nicht als Prototyp von irgendetwas benutzt. Es ist nur ein Objekt, das einer Eigenschaft namens prototype auf der Objektinstanz Foo zugewiesen ist.

var f = new Foo(); 

Jetzt das Objekt als Prototyp verwendet, und zwar ist es der Prototyp des f Objekt durch den Aufruf new Foo erstellt.

ein paar Details zu ignorieren, diese Codezeile:

var f = new Foo(); 

... tut im Grunde diese:

// Create a blank object, giving it `Foo.prototype` as its prototype 
var f = Object.create(Foo.prototype); 

// Call` Foo` using that new object as `this` 
Foo.call(f); 

Wie ich sagen, dass ein paar Details auslässt, aber hoffentlich es hilft, klar zu machen, was die prototype Eigenschaft der Funktionen ist für ...

+2

Wahrscheinlich die größte Quelle der Verwirrung in Javascript ist, dass "x.prototype" und "Prototyp von x" verschiedene Dinge sind. – georg

+0

@ thg435: Einverstanden. –

+0

jetzt bin ich mehr verwirrt :(.... Was ist der Unterschied – Nav

2

Was zurückgegeben wird, ist ein Objekt.

>>> typeof Object.create(Object) 
<<< "object" 
>>> Object.create(Object) 
<<< Function {} 
//   ^^ 

Function ist der Name, den Chrome Konstruktor des Objekts adressiert. Siehe How are javascript class names calculated for custom classes in Chrome Dev Tools?


Diesen Teil der Antwort-Adressen @ phenomnomnominal Kommentar in der Frage, zu erklären, warum die erstellte Objekt erbt Funktion Eigenschaften wie call hat.

Der Object Konstruktor ist eine Funktion, und somit erbt von dem Function Prototyp:

>>> Object.call === Function.prototype.call 
<<< true 

So ein Objekt Object als Prototyp hat, wird auch einen Link zu dem Funktionsprototyp über Prototypkette hat:

>>> Object.create(Object).call === Function.prototype.call 
<<< true 

Und wie von @TJ erwähnt, ist die Verwendung eines Konstruktors als Prototyp ziemlich merkwürdig.Sie sollten ein Objekt als den Prototyp angeben, von dem das erstellte Objekt erben wird. @TJ hat diesen Teil schon ziemlich gut erklärt.

Verwandte Themen