2012-05-01 1 views
10

Guardando sotto il cofano in UnderscoreJS, vedo:Perché UnderscoreJS usa toString.call() invece di typeof?

_.isFunction = function(obj) { 
    return toString.call(obj) == '[object Function]'; 
    }; 

    _.isString = function(obj) { 
    return toString.call(obj) == '[object String]'; 
    }; 

    _.isNumber = function(obj) { 
    return toString.call(obj) == '[object Number]'; 
    }; 

Questo mi sembra una scelta strana. Perché non usare solo typeof per determinare se un valore è una stringa, una funzione o un numero? C'è un guadagno in termini di prestazioni usando toString? Typeof non è supportato dai browser più vecchi?

+0

'typeof' esiste in ogni versione di JavaScript dalla versione 1.1 nel 1996. –

risposta

13

Beh, in effetti questo è perché è più veloce controllare lo [[Class]] controllando con toString. Inoltre ci potrebbe essere meno errori, dal momento toString ti dà la classe esatto ...

controllo questo:

var fn = function() { 
    console.log(typeof(arguments)) // returns object 
    console.log(arguments.toString()) // returns object Arguments 
} 

Si poteva vedere il punto di riferimento per sottolineatura typeof vs toString qui:

http://jsperf.com/underscore-js-istype-alternatives

Inoltre ci sono alcuni problemi github con spiegazione migliore:

https://github.com/documentcloud/underscore/pull/332

https://github.com/documentcloud/underscore/pull/321

EDIT 1:

Si potrebbe anche verificare questo grande articolo: risposta

http://javascriptweblog.wordpress.com/2011/08/08/fixing-the-javascript-typeof-operator/

+0

Ottimi riferimenti. Grazie! –

+1

/! \ Http://jsperf.com/underscore-js-istype-alternatives/7 (? Risposta di DriverDan) – BeauCielBleu

2

di drinchev è parzialmente corretto. toString è attualmente molto più lento di rispetto all'utilizzo di typeOf nella maggior parte dei browser. See the 7th revision of the test he posted che utilizza typeOf. Entrambe sono ancora molto veloci anche se, nella maggior parte dei casi, questa differenza di prestazioni non sarà evidente e il compromesso vale la pena di conformarsi alle specifiche meglio di duck typing/typeOf.

Underscore pull request 321 (che drinchev ha elencato) ha una discussione approfondita sui compromessi e sul motivo per cui hanno deciso di utilizzare toString.