为什么UnderscoreJS使用toString.call()而不是typeof

Why does UnderscoreJS use toString.call() instead of typeof?

本文关键字:typeof UnderscoreJS 使用 toString call 为什么      更新时间:2023-09-26

在UnderscoreJS的引擎盖下看,我看到:

  _.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]';
  };

这似乎是一个奇怪的选择。为什么不直接使用 typeof 来确定值是字符串、函数还是数字?使用 toString 是否有性能提升?旧版浏览器不支持 typeof 吗?

实际上这是因为

通过检查toString来检查[[Class]]更快。此外,错误可能会更少,因为 toString 为您提供了确切的类......

检查这个 :

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

您可以在此处查看下划线类型与 toString 的基准:

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

还有一些github问题需要更好的解释:

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

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

编辑 1 :

你也可以看看这篇很棒的文章:

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

Drinchev的回答部分正确。 toString 目前比在大多数浏览器中使用 typeOf 慢得多。请参阅他发布的测试的第 7 次修订版,该版本使用 typeOf。两者都仍然非常快,因此在大多数情况下,这种性能差异不会很明显,并且权衡值得比鸭子类型/typeOf更好地符合规格。

下划线拉取请求 321(drinchev 列出的)深入讨论了权衡以及他们决定使用 toString 的原因。