深入理解Object.prototype.toString.call()

点击去原文

为什么Object.toString.call([1,2,3])返回[object Array]?可以直接[].toString()返回[object Array]吗?
难道真的像自己理解的那样,是通过call将[1,2,3]作为Object.toString的实参传递了进去吗?不是。
直接Object.toString([1,2,3])不能实现同样的功能吗?不能。
而实际上也有Array.__proto__.toString()这种形式,所以是可以直接调用arr.toString()的,这样能检测出吗?不行。

那到底是什么原因?
先来肝一个表格。


数据类型例子return
字符串"foo".toString()"foo"
数字1.toString()Uncaught SyntaxError: Invalid or unexpected token
布尔值false.toString()"false"
undefinedundefined.toString()Uncaught TypeError: Cannot read property 'toString' of undefined
nullnull.toString()Uncaught TypeError: Cannot read property 'toString' of null
StringString.toString()"function String() { [native code] }"
NumberNumber.toString()"function Number() { [native code] }"
BooleanBoolean.toString()"function Boolean() { [native code] }"
ArrayArray.toString()"function Array() { [native code] }"
FunctionFunction.toString()"function Function() { [native code] }"
DateDate.toString()"function Date() { [native code] }"
RegExpRegExp.toString()"function RegExp() { [native code] }"
ErrorError.toString()"function Error() { [native code] }"
PromisePromise.toString()"function Promise() { [native code] }"
ObejctObject.toString()"function Object() { [native code] }"
MathMath.toString()"[object Math]"

为什么会出现下面的情况?

Object.toString.call(Array)//"function Array() { [native code] }"
Object.prototype.toString.call(Array)//"[object Function]"

答案在这里!

Object.toString()//"function Object() { [native code] }"
Object.prototype.toString()//"[object Object]"

Object对象和它的原型链上各自有一个toString()方法,第一个返回的是一个函数,第二个返回的是值类型。

既然知道了不同,现在我们再来分析下Object.prototype.toString.call(Array)//"[object Function]"
Array对象本身返回一个构造函数,Array//ƒ Array() { [native code] },而Object.prototype.toString()返回的是//"[object Type]"的形式,通过call将Array的this上下文切换到Object,从而调用了Object.prototype.toString(),因此返回[object Function]

需要注意的是:Math.toString()直接返回"[object Math]"。

实际开发中,我们用到最多的可能是:Object.prototype.toString.call([1,2,3])//"[object Array]"这种。

总结:

  • 一般情况下,js中对象的toString(),返回字符串,内容与函数声明语法有关,例如[1,2,3].toString()//"1,2,3"
  • 大多数都返回函数的完整源码,Array.toString()//"function Array() { [native code] }"
  • 内置函数往往返回一个类似"[native code]"的函数体,需要配合call方法,比如Object.prototype.toString.call([1,2,3])//"[object Array]"

那么不可以直接Array.prototype.toString.call([1,3,4])吗?
不行!
因为Array,Function,Date虽然是基于Object进行创建的,但是他们继承的是Object.toString(),而不是Object.prototype.toString()。
再加深一遍印象:

Object.toString()//"function Object() { [native code] }"
Object.prototype.toString()//"[object Object]"

所以这就是必须用Object.prototype.toString()去检测类型的原因。

至于Object.prototype.toString()内部是怎么实现的,等到时机成熟再去深入。

  • 5
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值