Perché ",,," == Array (4) in Javascript?


119

Avvia il tuo interprete / console e prova il confronto

> ",,," == Array(4)
True

Perché? All'inizio ho pensato che forse visto che potresti pensare a ",,," come un array di quattro caratteri con una fetta di terminazione "\ 0", potrebbe essere il motivo, ma

> "..." == Array(4)

Restituisce "False". Allora ... perché? So che è un po 'strano di dattilografia in Javascript, ma sono solo curioso di cosa sottolinea questo comportamento. Ho tratto questo dall'eccellente presentazione di Zed Shaw qui tra l'altro .


14
Pochi linguaggi oltre al C usano la terminazione zero in un modo visibile al programmatore.
Joey

7
Se posso chiedere, cosa ha portato a questa scoperta?
SomeKittens

1
@SomeKittens Zed Shaw lo menziona esplicitamente nel video a cui ho collegato nella mia domanda (come critica a Javascript). Saluti!
ZenLikeThat

5
@SomeKittens Questo è anche menzionato nel (abbastanza noto) parlare "wat", che mostra alcune stranezze in Ruby e JavaScript destroyallsoftware.com/talks/wat
Cronco

5
Questo è uno dei tanti buoni motivi per usare sempre al ===posto di ==.
wprl

Risposte:


178

Perché l'operando di destra viene convertito in una stringa e la rappresentazione di stringa Array(4)è ,,,:

> Array(4).toString()
  ",,,"

Se si utilizza la funzione di costruzione dell'array e si passa un numero, viene impostata la lunghezza dell'array su quel numero. Quindi puoi dire di avere quattro indici vuoti (come [,,,]) e la rappresentazione di stringa predefinita degli array è un elenco separato da virgole dei suoi elementi:

> ['a','b','c'].toString()
  "a,b,c"

Il modo in cui funziona il confronto è descritto nella sezione 11.9.3 delle specifiche . Lì vedrai ( x == y):

8. Se Type ( x ) è String o Number e Type ( y ) è Object,
restituisce il risultato del confronto x == ToPrimitive ( y ).

(gli array sono oggetti in JavaScript)

e se segui il ToPrimitivemetodo alla fine scoprirai che chiama toString.


2
Ok, ora tutto questo ha senso per me. Grazie.
ZenLikeThat

6
Il che, a sua volta, è dovuto al fatto che gli array si stringono come se stessero usando Array.join(",").
duskwuff -inattivo-

Devi essere maledettamente paziente per programmare in javascript
matcheek


31

Prova a usare ===. Quando si utilizza ==in Javascript, tenterà di eseguire il cast delle variabili, portando così a problemi come questo. La console esegue Array(4)il casting sulla rappresentazione di stringa (cioè Array(4).toString), che è ",,,". Il motivo per cui le virgole sono presenti è che la .toString()funzione le aggiunge a elementi separati in un array.

Vedi lo snippet di seguito:

document.write( Array(4).toString() );


18

Questo perché Array(4)inizializza un array di 4 valori vuoti, ==converte implicitamente, quindi:

 ",,," == Array(4)

 ",,," == Array(4).toString()

 ",,," == ["", "", "", ""] // note 3 commas for 4 values

 ",,," == ["", "", "", ""].toString()

Sono tutti simili.

==esegue conversioni di tipo implicite prima di confrontare i valori, il che può portare a risultati imprevedibili. Utilizzare ===per verificare il tipo e il valore.


5

Il confronto di un array con una stringa fa sì che l'array diventi una stringa prima di eseguire il confronto. La coercizione di un array vuoto di 4 elementi in una stringa produce quella stringa esatta.


4

All'inizio ho pensato che fosse qualcosa con il "prototipo" ... ma dopo una piccola indagine sono arrivato a una triste conclusione ...

Apparentemente è una cosa interna e più oscura con poca logica ...

Prova

Array(4)==Array(4)

e nessuna coercizione sui tipi anche ...

Array(4)===Array(4)

e otterrai FALSE

lo sai null==null, null===nulle anche undefined==undefinede undefined===undefinedrestituisce VERO ... quindi ... è un po 'oscuro ...

Array(4)==[,,,] dovrebbe essere vero anche


ZEE, Array (4) == [,,,] non sarà vero. Se confrontiamo oggetto con primitivo, l'oggetto verrà convertito in primitivo. Questo è il motivo per cui chiama toString ().
devsathish

array (x) dovrebbe essere l'indirizzo del costruttore ... comunque, in un sistema (non preoccuparti del tipo di sistema), <identity_X> === <identity_X> potrebbe sempre essere vero!
ZEE
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.