2015-01-01 5 views
21

ECMAScript In 6 wird ein neues Symbol Symbol.toPrimitive eingeführt wird, die, wenn sie als Objektschlüssel verwendet wird, eine Funktion der should defineGrundwert eines Objekts zurückzukehren:Symbol.toPrimitive vs Object.prototype.valueOf

let object = { 
    aNumber: 0, 
    [Symbol.toPrimitive]() { 
     return this.aNumber; 
    } 
}; 

object.aNumber = 5; 
console.log(object + 2) // 7 

Allerdings gibt es auch die Object.prototype.valueOf Funktion, die according to the documentation, neu definiert werden könnte, um ein Objekt zu dem Grundwert zu konvertieren:

let object = { 
    aNumber: 0, 
    valueOf() { 
     return this.aNumber; 
    } 
}; 

object.aNumber = 5; 
console.log(object + 2) // 7 

Also, welche dieser Möglichkeiten ein Objekt in seinen ursprünglichen Wert zu konvertieren, sollte in ES6 verwendet werden, wenn ein neues Objekt definiert wird?

+1

[Spec] (http://people.mozilla.org/~jorendorff/es6-draft.html#sec-toprimitive) -> _Die abstrakte Operation ToPrimitive verwendet ein Eingabeargument und ein optionales Argument PreferredType. Die abstrakte Operation ToPrimitive konvertiert ihr Eingabeargument in einen Nicht-Objekttyp. Wenn ein Objekt in mehr als einen primitiven Typ konvertiert werden kann, kann es den optionalen Hinweis PreferredType verwenden, um diesen Typ zu bevorzugen._ - Wenn es kein benutzerdefiniertes '.toPrimitive()' gibt, wird das Ergebnis von '.valueOf()' zurückgegeben – Andreas

+0

@Andreas Der Absatz, mit dem Sie verknüpft sind, bezieht sich nicht auf die 'Symbol'-Spezifikation, sondern auf die Umwandlung von _any_ nicht-primitiven Werten in primitive. Die entsprechende Spezifikation für 'Symbol.toPrimitive' lautet [in Absatz 19.4.3.4.] (Https://people.mozilla.org/~jorendorff/es6-draft.html#[email protected]@toprimitive) –

Antwort

10

Der Hauptzweck von Symbol.toPrimitive besteht darin, die Reihenfolge zu ändern, in der toString und valueOf in verschiedenen Zwangsszenarien aufgerufen werden.

Ein Beispiel hierfür ist das Date natives Objekt, in dem er den Wert in einen String statt einer Nummer standardmäßig konvertieren:

console.log(1 + new Date()); // "1Mon Aug 15 2016 13:25:31 GMT-0500 (EST)" 

var a = new Date(1000); 
console.log(a == 1000); // false 
console.log(a == a.toString()); // true 

Wenn Sie dies nicht möchten, tun sollten Sie nur überschreiben Sie sowohl obj.valueOf als auch obj.toString, um das gewünschte Verhalten zu erreichen. Dies ist das, was die meisten nativen Objekte in JavaScript tun.

Beachten Sie, dass beide valueOfundtoString außer Kraft gesetzt werden sollte, da die ToPrimitive abstrakte Operation eine von ihnen für Zwang je nach dem Grund nennen können ToPrimitive aufgerufen wird.

+1

'Symbol' wird jetzt in allen modernen Browsern unterstützt (ohne IE11), und' Symbol.toPrimitive' ist [wird derzeit von Chrome, Firefox und Node unterstützt] (http://kangax.github.io/compat-table/es6/ # test-well-known_symbols_Symbol.toPrimitive). – rvighne

+1

@rvighne Danke für die Erinnerung, ich habe die Antwort aktualisiert. –

+0

Auch 'Symbol.toPrimitive' wird mit einem Argument aufgerufen, das angibt, in welchen Typ es konvertiert werden soll (" default "." Number "oder" string ") – jcubic