2015-01-01 11 views
21

In ECMAScript 6, un nuovo Symbol.toPrimitive simbolo viene introdotta, che, quando utilizzato come chiave oggetto, should define una funzione per restituire il valore primitivo di un oggetto:Symbol.toPrimitive vs Object.prototype.valueOf

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

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

Tuttavia, v'è anche la funzione Object.prototype.valueOf, che, according to the documentation, potrebbe essere ridefinito per convertire un oggetto per il valore di base:

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

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

Quindi, quale di questi modi per convertire un oggetto al suo valore primitivo dovrebbe essere usato in ES6 quando si definisce un nuovo oggetto?

+1

[Spec] (http://people.mozilla.org/~jorendorff/es6-draft.html#sec-toprimitive) -> _L'operazione astratta ToPrimitive accetta un argomento di input e un argomento opzionale PreferredType. L'operazione astratta ToPrimitive converte l'argomento di input in un tipo non Object. Se un oggetto è in grado di convertire in più di un tipo primitivo, può usare l'hint opzionale PreferredType per favorire quel tipo._ - Se non c'è custom '.toPrimitive()' viene restituito il risultato di '.valueOf()' – Andreas

+0

@Andreas Il paragrafo a cui si è collegati è correlato non alla specifica 'Symbol', ma alla conversione di qualsiasi valore non primitivo in uno primitivo. La specifica corrispondente per 'Symbol.toPrimitive' è [nel paragrafo 19.4.3.4.] (Https://people.mozilla.org/~jorendorff/es6-draft.html#[email protected]@toprimitive) –

risposta

10

Lo scopo principale di Symbol.toPrimitive è di modificare l'ordine in cui sono chiamati toString e valueOf in diversi scenari di coercizione.

Un esempio di questo è l'oggetto nativo Date, dove sarà convertire il valore in una stringa invece di un numero di default:

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 

Se non si ha intenzione di fare questo, si deve solo sostituisci sia obj.valueOf sia obj.toString in modo che corrisponda al comportamento desiderato: questo è ciò che la maggior parte degli oggetti nativi esegue in JavaScript.

notare che sia valueOfetoString dovrebbero essere ignorate, come ToPrimitive operazione astratta può chiamare una di esse per coercizione seconda del motivo ToPrimitive viene chiamato.

+1

'Symbol' è ora supportato in tutti i browser moderni (sans IE11), e' Symbol.toPrimitive' è [attualmente supportato da Chrome, Firefox e Node] (http://kangax.github.io/compat-table/es6/ # test-ben-known_symbols_Symbol.toPrimitive). – rvighne

+1

@rvighne Grazie per il promemoria, ho aggiornato la risposta. –

+0

Viene chiamato anche 'Symbol.toPrimitive' con un argomento che indica quale tipo deve essere convertito in (" default "." Numero "o" stringa ") – jcubic

Problemi correlati