本文已参与[新人创作礼]活动,一起开启掘金创作之路。
话不多说,先上图
刚开始看的时候,也是一脑门问号,下面就来详细展开说下。
一、Object.prototype.toString和toString
官方定义,toString()方法返回一个表示该对象的字符串。所以toString是对象方法,全局对象也继承自Object,所以方法名相等:Object.prototype.toString === toString为true。
方法执行时的this,是在调用的时候赋值的
例如:
var obj = {
a: '输出a',
test() {
console.log(this.a)
}
}
var test = obj.test;
test(); // undefined
obj.test(); // 输出a
所以Object.prototype.toString() === toString()为false
二、Object.prototype.toString.call
call方法是用来改变this指向的,也就是讲传入的数据最终this都指到Object上去。
但是由于Array,Function等改写了toString方法,因此在我们想做类型判断时只能使用Object.prototype.toString.call方法,使用call函数改变this指向后正确输出了类型字符串。
// 定义一个数组
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
// 每一个继承 Object 的对象都有toString方法,如果toString方法没有重写的话,会返回[Object type]
// 删除后的数组再次使用 toString() 时,会向上层访问这个方法,即 Object 的 toString()
console.log(arr.toString()) // '[object Array]'
// 这是跟使用call方法就是同样的效果了
console.log(Object.prototype.toString.call(arr)) // '[object Array]'
三、Object.prototype.toString.call()和Object.toString.call()的区别
虽然所有对象的原型链最顶端都是Object.prototype,但同时Object本身也是一个构造函数,继承于Function,Object本身没有toString,所以Object.toString最终通过原型链调用的是Function.prototype.toString。
Object.toString === Function.prototype.toString
前者调用的是Function.prototype.toString,后者调用的是Object原型对象的toString。
Function.prototype.toString.call()参数需要传递个函数,类型不对所以报错了。
四、判断数据类型的几种方式比较
1.typeof
typeof是个一元运算符,用来返回js类型的字符串
主要返回值有:number、boolean、string、function、object、undefined
typeof null
// object
typeof undefined
// undefined
typeof NaN
number
2.instanceof
用来检测引用数据类型,返回true或false,比如判断a是否是b的实例:
a instanceof b
[] instanceof Array
// true
3.Object.prototype.toString.call
用于判断浏览器内置对象,自定义对象返回[Object Object]
参考: