Object.prototype.toString.call(obj)
这句话的意思是让我们用Object原型上的toString方法(见下图原型链)作用在传入的obj中(通过call将this指向obj),然后返回obj的类型。
那么我们知道数组或者其他引用类型本身也有toString()方法,那我们为什么非要用Object.prototype呢?
图一:原型链图
我们先来看下Array等类型的toString方法的输出
图二:不同类型上的toString方法
除了null和undefined和单独的数字上没有toString方法之外,其他基本类型或者引用类型都自带一个toString方法
我们又知道,在JavaScript中,所有类都继承于Object,因此toString()方法应该也被继承了,但由上述可见事实并不像我们想的那样,其实各数据类型使用toString()后的结果表现不一的原因在于:所有类在继承Object的时候,改写了toString()方法。
接下来让我们进行验证
// 定义一个数组
var arr = [1, 2, 3]
// 数组原型上是否具有 toString() 方法
console.log(Array.prototype.hasOwnProperty('toString')) //true
// 数组直接使用自身的 toString() 方法
console.log(arr.toString()) // '1,2,3'
// delete操作符删除数组原型上的 toString()
delete Array.prototype.toString
// 删除后,数组原型上是否还具有 toString() 方法
console.log(Array.prototype.hasOwnProperty('toString')) //false
// 删除后的数组再次使用 toString() 时,会向上层访问这个方法,即 Object 的 toString()
console.log(arr.toString()) // '[object Array]'
delete Array.prototype.toString,见下图①,删除了从Foo()到Foo.prototype的显示原型
console.log(arr.toString()) // '[object Array]',见下图②,最终Foo没有继承到Foo.prototype里边的toString,Foo就会顺着原型链往上找,最终找到Object.prototype上的toString
图三:验证Array上的toString是改写了的Object.prototype上的toString
ok,这样就屡明白了~
参考文章:浅谈Object.prototype.toString.call(obj)功能及原理_寒烟说的博客-优快云博客_object.prototype.tostring.call原理