2016-07-10 6 views

risposta

8

tutto dipende dal suggerimento. quando si utilizza 1 + o è un suggerimento di numero a causa dell'operando + in modo da utilizzare definitivamente lo valueOf prima dello toString.

Se il suggerimento è String, quindi toString viene utilizzato prima dello valueOf.per esempio provare ["o",o].join("=")

Tutti insieme sarebbe:

var o = {}; 
o.toString = function() {return 1}; 
o.valueOf= function(){return 2}; 
1 + o; // 1+2=3 ==> it takes valueOf value 
["o",o].join("") //o1 ==> it takes toString value 
+1

Grazie per il suggerimento circa il suggerimento. È sicuramente indicato come un numero. Ho modificato la mia risposta grazie alla tua .. –

+0

grazie, come determinare cosa è suggerimento? quali tipi di suggerimenti esistono? Il suggerimento è collegato all'operatore '+'? –

+1

@Maximus il suggerimento è semplicemente un indizio di tipo per JS per eseguire la sua azione. Nel nostro contesto verrebbe utilizzato solo uno dei due tipi (String, Number). In JS ci sono 6 tipi (indefinito, null, stringa, numero, oggetto, booleano). nel nostro caso Sì + L'operatore fornisce un suggerimento al motore JS per agire con questo valore come numero e utilizzare il metodo valueOf() prima di toString() –

10

Suppongo che la spiegazione sta nella 8.6.2.6 capitolo della ECMA-262 specification:

8.6.2.6 [DefaultValue]

[...]

Quando il [[DefaultValue] ] metodo di O è chiamato con suggerimento numero, i seguenti passi sono presi:

  1. Chiamare il metodo [[Ottieni]] dell'oggetto O con argomento "valueOf".

  2. Se Risultato (1) non è un oggetto, passare al punto 5.

  3. chiamata la [[Chiamata]] Metodo Risultato (1), con O come questo valore e un vuoto lista di argomenti.
  4. Se Risultato (3) è un valore primitivo, restituire Risultato (3).

  5. Chiamare il metodo [[Ottieni]] dell'oggetto O con argomento "toString".

  6. Se Risultato (5) non è un oggetto, passare al punto 9.

  7. chiamata la [[Chiamata]] Metodo Risultato (5), con O come questo valore e una lista di argomenti vuota .
  8. Se Risultato (7) è un valore primitivo, restituire Risultato (7).
  9. Genera un errore di runtime. Quando il metodo [[DefaultValue]] di O viene chiamato senza alcun suggerimento, si comporta come se il suggerimento fosse Numero, a meno che O non sia un oggetto Date (vedere la sezione 15.9), nel qual caso si comporta come se il suggerimento fosse Stringa.

Poiché l'oggetto non implementa valueOf, viene utilizzato toString.

+1

E 'vero, ma penso che vale la pena di menziona anche ** 11.6.1 L'operatore di addizione (+) **, che dice 7. ** Se Tipo (Risultato (5)) è String o Type (Result (6)) è String, andare al punto 12. **, dove Result (5) è ** Call ToPrimitive (Result (2)). **. Questo è il motivo per cui la somma deve accedere al valore predefinito e ha un comportamento diverso in base al tipo di valore predefinito – rpadovani

4

TL; DR

Quando ToPrimitive viene richiamata senza hint si comporta come se il suggerimento era number. Ciò definisce i metodi da chiamare: prima valueOf quindi toString. Se non hai definito il tuo valueOf chiamerà Object.prototype.valueOf che restituisce questo.

BTW nei browser moderni si può essere più specifico su di esso

const a = { 
    [Symbol.toPrimitive]: function(hint) { 
     console.log(hint); 
     return { 
      'default': 1, 
      'number': 2, 
      'string': 'three' 
     }[hint] 
    } 
} 

console.log(a + 1); //default, 2 
console.log(+a + 1); //number, 3 
console.log(`${a} + one`); //string, three + one 

Leggi Long:

  1. Addition
  2. ToPrimitive