2015-01-01 8 views
21

W ECMAScript 6 nowy Symbol.toPrimitive symbol jest wprowadzona, która użyta jako klucz obiektu, should define funkcja zwraca wartość prymitywne obiektu:Symbol.toPrimitive vs Object.prototype.valueOf

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

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

jednak istnieje również funkcja Object.prototype.valueOf, które according to the documentation, może być na nowo przekonwertować obiekt do wartości pierwotnej:

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

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

Więc, który z tych sposobów aby przekonwertować obiekt na jego prymitywną wartość powinien być użyty w ES6 podczas definiowania nowego obiektu?

+1

[Spec] (http://people.mozilla.org/~jorendorff/es6-draft.html#sec-toprimitive) -> _Funkcja abstrakcyjna ToPrimitive przyjmuje argument wejściowy i opcjonalny argument PreferredType. Operacja abstrakcyjna ToPrimitive przekształca argument wejściowy na typ inny niż Object. Jeśli obiekt jest zdolny do konwersji na więcej niż jeden typ pierwotny, może użyć opcjonalnej wskazówki PreferredType, aby faworyzować ten typ._ - Jeśli nie ma niestandardowego '.toPrimitive()' zwracana jest reesult z '.valueOf()' – Andreas

+0

@Andreas Paragraf, z którym się łączyłeś, nie jest powiązany ze specyfikacją "Symbol", ale z konwersją wartości _any_ nieprostu na pierwotną. Odpowiednia specyfikacja dla "Symbol.toPrimitive" jest [w paragrafie 19.4.3.4.] (Https://people.mozilla.org/~jorendorff/es6-draft.html#[email protected]@toprimitive) –

Odpowiedz

10

Głównym celem Symbol.toPrimitive jest zmiana kolejności wywoływania toString i valueOf w różnych scenariuszach przymusu.

Przykładem tego jest Date natywną obiektu, gdzie będzie on konwersji wartości na ciąg zamiast numeru domyślnie:

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 

Jeśli nie zamierzają tego robić, zalecana tylko Zastąp obie opcje: obj.valueOf i obj.toString, aby dopasować zachowanie, które chcesz - to właśnie robi większość obiektów natywnych w JavaScript.

Należy zauważyć, że zarówno valueOfitoString powinny zostać zastąpione, ponieważ ToPrimitive streszczenie operacja może wywołać jedną z nich przymusu w zależności od przyczyny ToPrimitive jest nazywany.

+1

'Symbol' jest teraz obsługiwany we wszystkich nowoczesnych przeglądarkach (sans IE11), a' Symbol.toPrimitive' jest [obecnie obsługiwany przez Chrome, Firefox i Node] (http://kangax.github.io/compat-table/es6/ # test-well-known_symbols_Symbol.toPrimitive). – rvighne

+1

@rvighne Dzięki za przypomnienie, zaktualizowałem odpowiedź. –

+0

Wywoływane jest również 'Symbol.toPrimitive' z jednym argumentem wskazującym, który typ powinien zostać przekonwertowany na (" default "." Number "lub" string ") – jcubic