为啥要使用 toString() 对可以使用 typeof 进行检查的参数进行类型检查?

Posted

技术标签:

【中文标题】为啥要使用 toString() 对可以使用 typeof 进行检查的参数进行类型检查?【英文标题】:Why use toString() to typecheck args that you can check with typeof?为什么要使用 toString() 对可以使用 typeof 进行检查的参数进行类型检查? 【发布时间】:2012-03-19 17:42:59 【问题描述】:

我明白为什么需要使用Object.prototype.toString()String() 来检查数组,但typeof 不足以检查函数和字符串吗?例如,MDN 上 Array.isArray 的 polyfill 使用:

Object.prototype.toString.call(arg) == '[object Array]';

在数组的情况下非常清楚,因为您不能使用typeof 来检查数组。 Valentine 为此使用 instanceof:

ar instanceof Array

但是对于字符串/函数/布尔值/数字,为什么不使用typeof

jQuery 和 Underscore 都使用这样的东西来检查函数:

Object.prototype.toString.call(obj) == '[object Function]';

这不就相当于这样做了吗?

typeof obj === 'function'

甚至这个?

obj instanceof Function

【问题讨论】:

【参考方案1】:

我能想到的第一个原因是typeof null 返回object,这通常不是您想要的(因为null 不是一个对象,而是一个本身的类型)。

但是,Object.prototype.toString.call(null) 返回[object Null]

但是,正如您所建议的,如果您希望某个字符串或其他类型可以很好地与typeof 配合使用,我认为您没有理由不能使用typeof(我经常使用typeof在那种情况下)。

您提到的那些库使用他们选择的方法的另一个原因可能只是为了保持一致性。您可以使用typeof 来检查Array,因此请使用另一种方法并始终坚持使用。

更多信息,Angus Croll has an excellent article on the typeof operator。

【讨论】:

我说的是检查那些看似应该正常工作的东西,比如字符串/函数/布尔值/数字 请注意,它不适用于 Promises,至少在 Firefox 中的 Chrome 中是这样。 typeof mypromise === 'object, toString.call(mypromise) === '[Object]', 但mypromise instanceof Promise === true @Hurelu - 在最新的稳定版 Chrome 中,我得到 "[object Promise]" for Object.prototype.toString.call(mypromise) 有趣。刚刚升级到 Chrome 43.0.2357.81,我仍然得到[object Object]。我只通过控制台检查。我还在 Firefox 中再次检查,[object Promise] 现在正确了。由于这些混合的结果,我仍然会提醒不要使用这种可靠地检测承诺的方法。【参考方案2】:

好的,我想我知道为什么您会看到 toString 的用法。考虑一下:

var toString = Object.prototype.toString;
var strLit = 'example';
var strStr = String('example')​;
var strObj = new String('example');

console.log(typeof strLit); // string    
console.log(typeof strStr); // string
console.log(typeof strObj); // object

console.log(strLit instanceof String); // false
console.log(strStr instanceof String); // false
console.log(strObj instanceof String); // true

console.log(toString.call(strLit)); // [object String]
console.log(toString.call(strStr)); // [object String]
console.log(toString.call(strObj)); // [object String]

【讨论】:

请注意,它不适用于 Promises,至少在 Firefox 中的 Chrome 中是这样。 typeof mypromise === 'object, toString.call(mypromise) === '[Object]', 但mypromise instanceof Promise === true @Hurelu 这是有道理的,因为Promise 继承自Object。我使用.call 得到"[object Object]",但如果你使用promise.toString,它会给出"[object Promise]"。见***.com/q/27746304/770127

以上是关于为啥要使用 toString() 对可以使用 typeof 进行检查的参数进行类型检查?的主要内容,如果未能解决你的问题,请参考以下文章

为啥要重写toString方法和hashcode方法

为啥要使用 SqlDataReader 的 GetOrdinal() 方法

为啥实体框架不能在 LINQ 语句中使用 ToString()?

为啥 ToString 使用不正确的小数分隔符格式化数字

php魔术方法__tostring

Java:为啥 \t 转义字符与 toString() 不一致? [复制]