2015-11-23 12 views
6

Ich habe eine Person Funktion Konstruktor wie so mit der Methode sayHelloEigenschaft auf dem Prototyp überschreibt die Eigenschaft des tatsächlichen Objekts?

var Person = function(firstName,lastName) { 
    this.lastName = lastName; 
    this.sayHello = function() { 
    return "Hi there " + firstName; 
    } 
}; 

Dann eine andere Version der sayHello Methode auf dem Prototyp Person Ich definiere:

Object.defineProperties(Person.prototype,{ 
    sayHello: { 
    value: function() { 
     return 'Hi there'; 
    }, 
    enumerable: true 
    } 
}); 
Jetzt

wenn ich eine Person erstellen Instanz und rufen sayHello darauf - Ich stelle fest, dass es die Version von sayHello verwendet, die auf dem Prototyp definiert ist.

var JoeBlow = new Person('Joe','Blow'); 

> JoeBlow.sayHello() 
< "Hi there" // I was expecting "Hi there Joe" 

Das ist für mich verwirrend.

Warum verwendet das JoeBlow-Objekt nicht seine eigene Implementierung von sayHello, anstatt sayHello auf seinem Prototypobjekt nachzuschlagen?

+0

Ich bin mir nicht sicher, aber Sie versuchen auch, einen 'firstname' anstelle von' this.firstname' zu ​​erhalten. möglich, dass Sie den 'this.firstname = firstname' verpasst haben und dann eine Rückgabe erhalten können. Weil es 'defined' mit einer Quentin-Antwort –

+0

@nAz zurückgibt -' Vorname' ist eine Variable, die hier definiert wird - '(firstName, lastName)' - und ist immer noch im Gültigkeitsbereich für den in der Konstruktorfunktion definierten Funktionsausdruck. Ich habe den Code in meiner Antwort getestet und es gibt "Hi there Joe" zurück. – Quentin

+0

@Quentin yeap du hast recht, ich habe etwas verpasst, darum habe ich es getestet und war überrascht. Danke –

Antwort

6

Standardmäßig sind die mit defineProperties definierten Eigenschaften Nur lesen.

Siehe MDN

writable
true if and only if the value associated with the property may be changed with an assignment operator.
Defaults to false.

Leider, wenn Sie eine Nur-Lese-Eigenschaft im alten Stil JS zu setzen versuchen, scheitert es still, anstatt eine Ausnahme zu werfen, so ist dies wirklich schwer zu debuggen.

Wenn Sie dies in strict mode laufen hatte, würde Sie bekommen haben:

TypeError: Cannot assign to read only property 'sayHello' of [object Object]

Sie können explizit die Eigenschaft definieren beschreibbar zu sein.

Object.defineProperties(Person.prototype,{ 
    sayHello: { 
    value: function() { 
     return 'Hi there'; 
    }, 
    enumerable: true, 
    writable: true 
    } 
}); 

Dann this.sayHello = function() { wird nicht unbemerkt fehlschlagen, und Sie werden erfolgreich die Version der Eigenschaft Maske auf dem Prototyp leben.

+0

Vielleicht missverstehe ich die Frage, aber wie beantwortet das, warum die Eigenschaftensuche die Prototypversion statt der ursprünglichen Version verwendet? Wie wirkt ** schreibbar ** die Version auf das Objekt selbst (oder zwingt die Engine stattdessen, die Prototypversion zu verwenden) – AmmarCSE

+0

@AmmarCSE - Die Prototypversion ** ist ** die Originalversion. Die Ersetzungsversion, mit der die Konstruktorfunktion es zu überschreiben versucht, schlägt fehl, da die Eigenschaft schreibgeschützt ist. Wenn die Eigenschaft schreibbar gemacht wird, kann 'this.sayHello = irgendwas' erfolgreich einen neuen Wert zugewiesen werden. – Quentin

+0

warte, sagst du, dass "Person.prototype" ist "Person" selbst? Ich dachte, in diesem Fall wäre es "Objekt" – AmmarCSE

Verwandte Themen