用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. XSS之Beef的使用

    0x01 Beef简介 BeEF是The Browser Exploitation Framework的缩写.它是一种专注于Web浏览器的渗透测试工具. beef管理.挂钩web浏览器的过程: 生成交 ...

  2. 简单聊聊CSS中的3D技术之“立方体”

    简单聊聊CSS中的3D技术之“立方体” 大家好,我是今天的男一号,我叫小博主. 今天来聊一下我在前端“逆战班”学习中遇到的颇为有趣的3D知识.前端学习3周,见识稀疏,在下面的分享中如有不对的地方请大家 ...

  3. 10maven依赖继承、统一版本/编码

    A >  B  >  C A依赖于B,B依赖于C,如果A想间接依赖C,那么B和C之间的依赖范围必须是compile,不然A依赖不了C 但是有点麻烦,因为每次A想依赖于C都要确认B和C之间的 ...

  4. 后台实战——用户登录之JWT

    https://blog.csdn.net/jackcheng_ht/article/details/52670211

  5. #4864. [BeiJing 2017 Wc]神秘物质 [FHQ Treap]

    这题其实挺简单的,有个东西可能稍微难维护了一点点.. \(merge\ x\ e\) 当前第 \(x\) 个原子和第 \(x+1\) 个原子合并,得到能量为 \(e\) 的新原子: \(insert\ ...

  6. Mac下安装MySQL8的问题

    黑苹果用了一段时间之后,发现很多方面用起来比Windows还舒服些,没什么具体指标,就是纯粹一种感觉. 所以,慢慢将很多程序都迁移过来,在迁移过程中发现的一些有意思的事儿,我都把他们记录下来.如果,不 ...

  7. pygame 运行心理学问卷

    import pygame import sys from pygame.locals import * # wait for keys to putdown def waitForKeys(keys ...

  8. Zjnu Stadium HDU - 3047 带权并查集板子题

    #include<iostream> #include<cstring> #include<cstdio> using namespace std; +; int ...

  9. [POI2005] SKA-Piggy Banks - DFS

    有N个小猪存钱罐.每一个存钱罐能够用相应的钥匙打开或者被砸开.Byteazar已经将钥匙放入到一些存钱罐中.现在已知每个钥匙所在的存钱罐,Byteazar想要买一辆小汽车,而且需要打开所有的存钱罐.然 ...

  10. BZOJ3926&&lg3346 ZJOI诸神眷顾的幻想乡(广义后缀自动机)

    BZOJ3926&&lg3346 ZJOI诸神眷顾的幻想乡(广义后缀自动机) 题面 自己找去 HINT 我们可以把题目拆解成几个部分,首先我们手玩一个结论,从所有的叶子节点出发,遍历整 ...