关于javascript的面试题,常常会问道判断数据类型,答案无非是typeof,instance of 之类的,但是它们都不能准确的判断,今天我们来讲一讲算是万能判断的方法 Object.prototype.toString.call
看到这一长串的链式调用,我们大概最主要的关注点在toString上,我们先打印下各种类型的数据toString最后打印的值(例举三例),如下图
var a=1;
console.log(a.toString()) //'1'
var a=true;
cosnol.log(a.toString()) //'true'
var a={
b:1
}
console.log(a.toString()) //[object Object]
下面是数据类型通过toString方法打印出的类型:
有兴趣的可以去尝试尝试~~~
由此可见,这就是各种数据类型调用toString()方法的返回值,由此我们看出不同的数据类型都有其自身toString()方法。所以上述toString()方法来自于Number、String、Boolean…等等这些类。
我们又知道,在JavaScript中,所有类都继承于Object,因此toString()方法应该也被继承了,但由上述可见事实并不像我们想的那样,其实各数据类型使用toString()后的结果表现不一的原因在于:所有类在继承Object的时候,改写了toString()方法。 Object原型上的方法是可以输出数据类型的。因此我们想判断数据类型时,也只能使用原始方法。继而有了此方法:Object.prototype.toString.call(obj)
让我们来验证一下
// 定义一个数组
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]'
当我们把Array自身的toString()方法删除之后,再次使用它时,由原型链它会向上查找这个方法,即Object的toString(),也便将Object上的toString()方法作用在数组上,得出其数据类型[object Array]
至此便透彻了Object.prototype.toString.call(obj)功能及原理。