2015-06-11 9 views
6

Visto nella mia newsletter. Testato su Chrome e Firefox. Non riesco ancora a capirlo.JavaScript: Perché [] + (- ~ {} - ~ {} - ~ {} - ~ {}) + (- ~ {} - ~ {}); restituisce "42"

[]+(-~{}-~{}-~{}-~{})+(-~{}-~{}); //=> "42" 
+0

qualcosa di mai visto così, sarò interrested di sapere di cosa si tratta. –

+1

Perché Javascript ha regole di coercizione numerica ridicole. (Ed è essenzialmente impossibile cercare istanze precedenti in cui questa domanda è stata posta.) –

+0

Se ti chiedi perché JS fa certe cose nel modo in cui lo fa, ti incoraggio a leggere le specifiche. Devi solo guardare http://www.ecma-international.org/ecma-262/5.1/#sec-11.4.8, http://www.ecma-international.org/ecma-262/5.1/# sec-11.4.7 e http://www.ecma-international.org/ecma-262/5.1/#sec-11.6.1 –

risposta

6

Valutare:

~{} 

viene valutata utilizzando la funzione interna:

~ToInt32({}) 

che dà -1.

Ref ECMA spec - http://www.ecma-international.org/ecma-262/5.1/#sec-9.5 e questa spiegazione - http://jibbering.com/faq/notes/type-conversion/#tcToInt32

Pertanto, in questo caso

(-~{}-~{}) == 2 
(-~{}-~{}-~{}-~{}) == 4 

Come avete []+ in partenza di espressione, javascript uso più operandi come stringa. In modo da avere "" + "4" + "2" = "42"

+0

Sei stato circa 20 secondi più veloce di me. :) – xxbbcc

+1

'~' è l'operatore Bitwise NOT. Converte '0' in' -1' – laggingreflex

+1

'{}! = Undefined' (Sentiti libero di testare questo). – Amit

3

L'operatore ~ è un operatore NOT bit a bit. Restituisce il "complemento 1" di un numero. Per questo motivo, {} viene convertito in un numero, risultante in NaN. Lo stesso accadrebbe con +{} == NaN. Bitwise non di ~NaN == -1. Quindi:
(-~{}-~{}-~{}-~{}) == 4 & (-~{}-~{}) == 2

Il DefaultValue per un array vuoto è una stringa vuota. Ad esempio []==[]+[] && []+[]==''

Da questo, il parsing completo è: []+ /*converted to ''+*/ (-~{}-~{}-~{}-~{}) /*Equals numeric 4, but concatenated as a string to become '4'*/ + (-~{}-~{}) /*Equals numeric 2, but concatenated as a string to become '2'*/ ed il risultato finale è in realtà '42'.

È possibile convalidare questa via typeof([]+(-~{}-~{}-~{}-~{})+(-~{}-~{})) === 'string'

Problemi correlati