2011-09-12 6 views
6

Ho appena stato a guardare la funzione di _.isEqual Underscore.js ed una sezione del codice più o meno così:Questa riga di Underscore.js esegue il controllo di uguaglianza effettivamente necessario?

if (a === b) return true; 

if (typeof a !== typeof b) return false; 

if (a == b) return true; 

Mi chiedo solo se c'è un caso in cui è stato possibile raggiungere la terza dichiarazione e valutare a true?

Edit: Giusto per essere chiari, questo non è il mio codice di cui sto parlando, sto leggendo la fonte di sottolineatura, in particolare, this line ed ero curioso di sapere il motivo per cui stanno facendo questo.

+1

Deve esserci qualche strano caso limite dove questo è possibile ... –

+0

@nickf: Considerando che '==' e '===' sono identici quando i tipi sono gli stessi, non riesco a vedere come il primo e il terzo test possano fornire un risultato diverso. Anche nel caso di 'null' dove il' typeof' differisce dal 'Type' interno, non costringe a nessun valore eccetto' undefined', che ha un valore 'typeof' diverso. E se ci * è * un caso limite là fuori, come fai a sapere che vorresti * che costringesse? Sembra strano avere un test '==' e a '===' degli stessi valori. O vuoi la coercizione di tipo o non lo fai. – user113716

+0

... Dovrei chiarire che con * "tu" * nel commento sopra, non intendevo implicare * nickf *, ma piuttosto * una persona *. – user113716

risposta

3

Ho appena controllato il repository Underscore e ho trovato una breve discussione in cui qualcuno ha chiesto the exact same thing e sembra che non sia effettivamente necessario.

Seguire l'algoritmo definito dalla specifica del linguaggio ECMAScript in section 11.9.6 e section 11.9.3 sembra indicare che nessuna coppia di valori deve restituire true nel caso precedente.

Quindi, in breve, no, questa situazione non è possibile.

+0

+1 Buona scoperta su quella discussione – user113716

1

L'unica situazione dove == e === reagiscono inaspettatamente è quando si confronta la stringa letterale ("123") ad una stringa costruito (new String("123")), che sicuro il primo test.

Tuttavia, nel secondo test viene rilevato perché la stringa costruita ha il tipo object, ma il letterale ha il tipo string.

In base a ciò, direi di no, la terza affermazione non può mai essere raggiunta, e la valutazione è vera.

1

Quando si utilizza l'operatore == e le espressioni sono di tipi diversi, JavaScript in genere convertirà i due nello stesso tipo prima di confrontarli.

Ad esempio, questo può accadere con null e undefined. null == undefined è vero, anche se null === undefined è falso. Tuttavia typeof null è "object", mentre typeof undefined è "undefined". Quindi, in questo caso dovresti restituire false nella seconda istruzione.

Potete leggere tutti i dettagli nella (sezione 11.9.3) spec, è molto coinvolta: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf

1

La mia ipotesi iniziale era che era per aggirare un'implementazione del browser rotto.

Tuttavia, dopo aver inserito nei log di git per quel file, sembra che la riga corrispondente sia stata nel primo controllo underscore.js. (Non ho intenzione di cacciare nel repository genitore documentcloud core.js ...) È possibile vederlo alla riga 334 del https://github.com/documentcloud/underscore/commit/02ede85b539a89a44a71ce098f09a9553a3a6890.

Quindi ora la mia ipotesi è che il suo solo cruft è stato lasciato in, mai completamente testato e mai pulito.

Problemi correlati