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


Posted in Javascript onOctober 11, 2018

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

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

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

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

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()呢?

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方法删除,看看会是什么结果:

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)相同的结果。

Javascript 相关文章推荐
在IE下获取object(ActiveX)的Param的代码
Sep 15 Javascript
JQuery的ajax获取数据后的处理总结(html,xml,json)
Jul 14 Javascript
JQuery.ajax传递中文参数的解决方法 推荐
Mar 28 Javascript
EXTJS FORM HIDDEN TEXTFIELD 赋值 使用value不好用的问题
Apr 16 Javascript
js实现Select下拉框具有输入功能的方法
Feb 06 Javascript
javascript实现表格增删改操作实例详解
May 15 Javascript
JavaScript高级程序设计(第三版)学习笔记6、7章
Mar 11 Javascript
微信小程序之购物车功能
Sep 23 Javascript
详解vue跨组件通信的几种方法
Jun 15 Javascript
详解从新建vue项目到引入组件Element的方法
Aug 29 Javascript
vue2.x select2 指令封装详解
Oct 12 Javascript
微信小程序开发之自定义tabBar的实现
Sep 06 Javascript
使用vue 国际化i18n 实现多实现语言切换功能
Oct 11 #Javascript
详解Angular5/Angular6项目如何添加热更新(HMR)功能
Oct 10 #Javascript
Node.js npm命令运行node.js脚本的方法
Oct 10 #Javascript
vue环形进度条组件实例应用
Oct 10 #Javascript
Node.js中读取TXT文件内容fs.readFile()用法
Oct 10 #Javascript
详解Node.js读写中文内容文件操作
Oct 10 #Javascript
angular6的响应式表单的实现
Oct 10 #Javascript
You might like
二次元帅气男生排行榜,只想悄悄收藏系列
2020/03/04 日漫
一个高ai的分页函数和一个url函数
2006/10/09 PHP
利用 window_onload 实现select默认选择
2006/10/09 PHP
PHP 函数执行效率的小比较
2010/10/17 PHP
php自动加载方式集合
2016/04/04 PHP
PHP基于自定义类随机生成姓名的方法示例
2017/08/05 PHP
在TP5数据库中四个字段实现无限分类的示例
2019/10/18 PHP
Thinkphp 框架配置操作之动态配置、扩展配置及批量配置实例分析
2020/05/15 PHP
在修改准备发的批量美化select+可修改select时,在非IE下发现了几个问题
2007/01/09 Javascript
Draggable Elements 元素拖拽功能实现代码
2011/03/30 Javascript
jquery插件star-rating.js实现星级评分特效
2015/04/15 Javascript
JavaScript 七大技巧(二)
2015/12/13 Javascript
JavaScript中split与join函数的进阶使用技巧
2016/05/03 Javascript
深入理解requestAnimationFrame的动画循环
2016/09/20 Javascript
JS库之Particles.js中文开发手册及参数详解
2017/09/13 Javascript
在js文件中引入(调用)另一个js文件的三种方法
2020/09/11 Javascript
[46:42]DOTA2-DPC中国联赛正赛 Aster vs Magma BO3 第二场 3月5日
2021/03/11 DOTA
python strip() 函数和 split() 函数的详解及实例
2017/02/03 Python
python OpenCV学习笔记实现二维直方图
2018/02/08 Python
Python实现多级目录压缩与解压文件的方法
2018/09/01 Python
python实现可逆简单的加密算法
2019/03/22 Python
关于python多重赋值的小问题
2019/04/17 Python
pybind11在Windows下的使用教程
2019/07/04 Python
加拿大最大的书店:Indigo
2017/01/01 全球购物
美国半成品食材配送服务商:Home Chef
2018/01/25 全球购物
HOTEL INFO英国:搜索全球酒店
2019/08/08 全球购物
Linux中如何设置Java环境变量(Ubuntu)
2016/07/24 面试题
迟到检讨书500字
2014/02/05 职场文书
讲文明树新风演讲稿
2014/05/12 职场文书
幼儿园小班家长评语
2014/12/30 职场文书
信贷客户经理岗位职责
2015/04/09 职场文书
公司催款律师函
2015/05/27 职场文书
挂职锻炼工作总结2015
2015/05/28 职场文书
关于感恩的歌曲整理(8首)
2019/08/14 职场文书
深入理解MySQL中MVCC与BufferPool缓存机制
2022/05/25 MySQL
解决spring.thymeleaf.cache=false不起作用的问题
2022/06/10 Java/Android