用Object.prototype.toString.call(obj)检测对象类型原因分析

 更新时间:2018年10月11日 08:46:33   投稿:laozhang    我要评论
 
在本篇文章里我们给大家剖析了用Object.prototype.toString.call(obj)检测对象类型的原因,需要的朋友们可以学习下。

这是一个十分常见的问题,用 typeof 是否能准确判断一个对象变量,答案是否定的,null 的结果也是 object,Array 的结果也是 object,有时候我们需要的是 "纯粹" 的 object 对象。如何避免呢?比较好的方式是:

1
console.log(Object.prototype.toString.call(obj) === "[object Object]");

使用以上方式可以很好的区分各种类型:

(无法区分自定义对象类型,自定义类型可以采用instanceof区分)

1
2
3
4
5
6
7
8
9
10
11
12
console.log(Object.prototype.toString.call("jerry"));//[object String]
console.log(Object.prototype.toString.call(12));//[object Number]
console.log(Object.prototype.toString.call(true));//[object Boolean]
console.log(Object.prototype.toString.call(undefined));//[object Undefined]
console.log(Object.prototype.toString.call(null));//[object Null]
console.log(Object.prototype.toString.call({name: "jerry"}));//[object Object]
console.log(Object.prototype.toString.call(function(){}));//[object Function]
console.log(Object.prototype.toString.call([]));//[object Array]
console.log(Object.prototype.toString.call(new Date));//[object Date]
console.log(Object.prototype.toString.call(/\d/));//[object RegExp]
function Person(){};
console.log(Object.prototype.toString.call(new Person));//[object Object]

为什么这样就能区分呢?于是我去看了一下toString方法的用法:toString方法返回反映这个对象的字符串。

那为什么不直接用obj.toString()呢?

1
2
3
4
5
6
7
console.log("jerry".toString());//jerry
console.log((1).toString());//1
console.log([1,2].toString());//1,2
console.log(new Date().toString());//Wed Dec 21 2016 20:35:48 GMT+0800 (中国标准时间)
console.log(function(){}.toString());//function (){}
console.log(null.toString());//error
console.log(undefined.toString());//error

同样是检测对象obj调用toString方法(关于toString()方法的用法的可以参考toString的详解),obj.toString()的结果和Object.prototype.toString.call(obj)的结果不一样,这是为什么?

这是因为toString为Object的原型方法,而Array ,function等类型作为Object的实例,都重写了toString方法。不同的对象类型调用toString方法时,根据原型链的知识,调用的是对应的重写之后的toString方法(function类型返回内容为函数体的字符串,Array类型返回元素组成的字符串.....),而不会去调用Object上原型toString方法(返回对象的具体类型),所以采用obj.toString()不能得到其对象类型,只能将obj转换为字符串类型;因此,在想要得到对象的具体类型时,应该调用Object上原型toString方法。

我们可以验证一下,将数组的toString方法删除,看看会是什么结果:

1
2
3
4
5
var arr=[1,2,3];console.log(Array.prototype.hasOwnProperty("toString"));//true
console.log(arr.toString());//1,2,3
delete Array.prototype.toString;//delete操作符可以删除实例属性
console.log(Array.prototype.hasOwnProperty("toString"));//false
console.log(arr.toString());//"[object Array]"

删除了Array的toString方法后,同样再采用arr.toString()方法调用时,不再有屏蔽Object原型方法的实例方法,因此沿着原型链,arr最后调用了Object的toString方法,返回了和Object.prototype.toString.call(arr)相同的结果。

用Object.prototype.toString.call(obj)检测对象类型原因分析的更多相关文章

  1. 为什么用Object.prototype.toString.call(obj)检测对象类型?

    最近做了做一些js面试25 Essential JavaScript Interview Questions*,其中第一道是:使用typeof bar === "object"检测 ...

  2. Object.prototype.toString.call(obj)检测数据类型

    typeof bar=='object' 不能确切判断数据是一个‘纯粹’的对象 Array null的结果都是object 比较好的方法是: Object.prototype.toString.cal ...

  3. Object.prototype.toString.call(obj)使用方法以及原理

    这几天看vue-router的源码 发现了Object.prototype.toString.call()这样的用法,当时以为这就是转成字符串的用的,但是越看越觉得不太对劲,赶紧查查资料,一查才知道没 ...

  4. Object.prototype.toString.call(obj).slice(8,-1)

    1.Object.prototype.toString() 该方法返回描述某个对象数据类型的字符串,如自定义的对象没有被覆盖,则会返回“[object type]”,其中,type则是实际的对象类型. ...

  5. 数据类型的判断 --Object.prototype.toString.call(obj)精准检测对象类型

    数据类型的判断 typeof typeof返回一个表示数据类型的字符串,返回结果包括:number.boolean.string.symbol.object.undefined.function等7种 ...

  6. js中通过Object.prototype.toString方法----精确判断对象的类型

    判断是否为函数 function isFunction(it) {        return Object.prototype.toString.call(it) === '[object Func ...

  7. 从toString()方法到Object.prototype.toString.call()方法

    一.toString方法和Object.prototype.toSting.call()的区别 var arr=[1,2]; 直接对一个数组调用toString()方法, console.log(ar ...

  8. js Object.prototype.toString.call()

    Object.prototype.toString.call(obj)使用方法以及原理   这几天看vue-router的源码 发现了Object.prototype.toString.call()这 ...

  9. Object.prototype.toString()

    Object.prototype.toString()方法返回一个代表该对象的字符串. var o = new Object(); o.toString(); //"[object Obje ...

随机推荐

  1. 小白的linux笔记2:关于进程的基本操作

    1.ps命令查看进程.ps -aux查看所有进程.可以用grep提取相关的部分进程,如只看python有关的:ps -aux |grep python. 进程状态:R运行中,T暂停,S休眠静止. 和进 ...

  2. 标准化建筑的 FRESH 原则

    前记 大家好,我是小镭. 我在钢结构领域从业十余年,虽然工作内容是关于建筑的,但如果问我什么是建筑,我却一时答不出来. 记得小时候我读过一篇文章,说建筑是凝固的音乐. 后来我看了些书,觉得建筑是空间. ...

  3. IIS7启用ASP程序的步骤。

    IIS7配置asp程序 https://www.cnblogs.com/rollup/p/4969502.html

  4. IntelliJ IDEA 2018.3.2 永久破解

    PS:动手能力强的来,手残的去淘宝买吧,大概15块钱1年.建议看完后在动手,有一个全局观,浪费不了多少时间 一. 下载破解补丁文件 链接:https://pan.baidu.com/s/1wFp14t ...

  5. ISE post-place&route仿真准备

    ISE post-place&route仿真准备 使用目的:post-place&route仿真是综合后考虑门延时而进行的仿真.因为考虑到各个门的延时,所以可以发现行为仿真(behav ...

  6. kafka消费服务调优

    1.消费服务速度跟不上 2.top -H 观察是哪个线程最忙 3.多次使用jstack,看看最忙的那个线程在做什么

  7. JS宣传页项目-综合实战

    按照国际惯例先放图 index.html <!DOCTYPE html> <html lang="en"> <head> <meta ch ...

  8. LeNet, AlexNet, VGGNet, GoogleNet, ResNet的网络结构

    1. LeNet 2. AlexNet 3. 参考文献: 1.  经典卷积神经网络结构——LeNet-5.AlexNet.VGG-16 2. 初探Alexnet网络结构 3.

  9. Python静态方法、类方法、属性方法

    静态方法 使用静态方法以后,相当于把下面的函数和类的关系截断了,它的作用相当于是类下面的一个独立函数,不会自动传入参数self. class people:..... @staticmethod de ...

  10. 小白月赛22 A : 操作序列

    A:操作序列 析题得说: 考察点 : 模拟,STL库容器的使用 坑点 : 区间不要搞丢东西 难点 : 这个题比较变态的是我们不知道每次输入每行是一个数还是两个数,就需要进行判断, 怎么判断呢?用 sc ...