为什么Object.prototype.toString.call()可以如此准确的判断对象类型?

4,290 阅读3分钟

本人已参与「新人创作礼」活动,一起开启掘金创作之路。

前言

typeof类型判断方式所带来的问题

小伙伴们应该都了解。常规我们用typeof 或者 instanceof对数据类型进行判断。他不一定是绝对准确的。

比如 typeof Array 和 typeof Object 亦或者是 typeof Date

得出的结果永远都是 'object',像这样↓

image.png

如果有小伙伴还不太了解各种类型判断之间的区别可以先去Javascript高级篇之类型判断的三种方式及其隐藏细节 - 掘金 (juejin.cn)这篇文章看看。

Object.prototype.toString().call() 类型判断

使用 Object.prototype.toString().call()这个方法却可以完美的判断数据类型。

像这样↓

image.png

Object.prototype.tostring.call()这个方法我想大部分小伙伴们都会用,但是他为什么可以精准判断呢?今天我们一起来看一看。

为什么Object.prototype.toString.call()可以准确判断数据类型

我们需要了解,不论是Array,还是Date,所有数据类型。都是从对象衍生而来的。本质上,Array和Date还有Function啥的他们就是对象。

虽然他们都被称为对象,对象也是有很多类型的。比如Date,他就是时间对象‘ [object Date] ’, Array,他就是数组对象‘[object Array]’等等。简而言之,js中所有的数据类型,都只是对象的一种类型。所以,js中有一句话叫,万物皆对象

而Object.prototype.toString() 这个函数作用就是,返回当前调用者的对象类型

让我们来看看官方对Object.prototype.toString的定义↓

image.png

Object.prototype.toString()会返回[object, [[class]]]的字符串

其中[[class]]会返回es定义的对象类型,包含"Arguments", “Array”, “Boolean”, “Date”, “Error”, “Function”, “JSON”, “Math”, “Number”, “Object”, “RegExp”, 和 “String”;

再加上es5新增加的返回[object Undefined]和[object Null]

言简意赅的说:所有数据类型都是对象的一种类型,而Object.prototype.toString可以返回当前调用者的对象类型。

image.png

Object.prototype.toString.call()为什么要加call();

因为Object.prototype.toString()返回的是调用者的类型。不论你toString()本身的入参写的是什么,在Object.prototype.toString()中,他的调用者永远都是Object.prototype;所以,在不加call()情况下,我们的出来的结果永远都是 '[object Object]'

call(),是为了改变Object.prototype.toString这个函数都指向。让Object.prototype.toString这个方法指向我们所传入的数据

为什么一定要用Object.prototype.toString.call()

有些小伙伴可以回疑惑了。为什么一定要用Object.prototype.toString.call()这个方法,那么长,写起来很麻烦,我直接在当前数据本身去调用toString(),然后让他顺着原型链去找,最后找到Object.prototype.toString这个方法不行吗?连call都省下了。

还真不行。

因为,每个数据类,他们都重写了toString()方法。所以,如果我们拿数据本身去toString(),是得不到对象类型的。

我们拿数组举个例子↓

image.png

image.png

我们在数组的原型上又发现了一个toString方法,证明toString方法被重写了。所以,直接使用数据本身去调用toString。是无法调用到Object.prototype.toString的。而且,在数组上被重写之后的toString方法,作用也不再是返回对象类型了。而是打印数组内容。

所以,我们只能使用Object.prototyoe.toString.call();的形式去获取对象属性

总结

  • js中所有的数据类型,本质上都是对象,而这些数据类型不过是对象的一种类型而已。
  • Object.prototype.toString这个方法是用于返回当前调用者的对象类型的
  • call是为了让Object.prototype.toString方法指向我们指定的数据。否则返回永远都是[object Object]
欢迎技术了解~

备注来自掘金~

WechatIMG322_副本.jpeg