用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 相关文章推荐
JavaScript 字符串乘法
Aug 20 Javascript
如何让页面在打开时自动刷新一次让图片全部显示
Dec 17 Javascript
jquery动态增加text元素以及删除文本内容实例代码
Jul 01 Javascript
让JavaScript的Alert弹出框失效的方法禁止弹出警告框
Sep 03 Javascript
JS实现双击屏幕滚动效果代码
Oct 28 Javascript
使用Script元素发送JSONP请求的方法
Jun 12 Javascript
jQuery获取attr()与prop()属性值的方法及区别介绍
Jul 06 Javascript
jQuery 常见小例汇总
Dec 14 Javascript
快速理解 JavaScript 中的 LHS 和 RHS 查询的用法
Aug 24 Javascript
完美解决axios跨域请求出错的问题
Feb 05 Javascript
JS实现图片上传多次上传同一张不生效的处理方法
Aug 06 Javascript
jQuery 常用特效实例小结【显示与隐藏、淡入淡出、滑动、动画等】
May 19 jQuery
使用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
php 正则 过滤html 的超链接
2009/06/02 PHP
PHP转换文件夹下所有文件编码的实现代码
2013/06/06 PHP
学习php设计模式 php实现备忘录模式(Memento)
2015/12/09 PHP
详解如何实现Laravel的服务容器的方法示例
2019/04/15 PHP
小型js框架veryide.librar源代码
2009/03/05 Javascript
javascript 写类方式之九
2009/07/05 Javascript
Jquery 表单取值赋值的一些基本操作
2009/10/11 Javascript
jQuery Ajax使用 全解析
2010/12/15 Javascript
网页编辑器ckeditor和ckfinder配置步骤分享
2012/05/24 Javascript
JS判断元素为数字的奇异写法分享
2012/08/01 Javascript
javascript重复绑定事件造成的后果说明
2013/03/02 Javascript
js实现连续英文字符自动换行兼容ie6 ie7和firefox
2013/09/06 Javascript
当前流行的JavaScript代码风格指南
2014/09/10 Javascript
Javascript小技能总结(推荐)
2016/06/02 Javascript
数据结构中的各种排序方法小结(JS实现)
2016/07/23 Javascript
javascript中的深复制详解及实例分析
2016/12/29 Javascript
Node.js和Express简单入门介绍
2017/03/24 Javascript
jQuery+ajax实现局部刷新的两种方法
2017/06/08 jQuery
vue修改vue项目运行端口号的方法
2017/08/04 Javascript
SelectPage v2.4 发布新增纯下拉列表和关闭分页功能
2017/09/07 Javascript
Angularjs Promise实例详解
2018/03/15 Javascript
vue.js实现图书管理功能
2019/09/24 Javascript
微信小程序利用云函数获取手机号码
2019/12/17 Javascript
Python登录注册验证功能实现
2018/06/18 Python
python读取文本中的坐标方法
2018/10/14 Python
如何基于python实现画不同品种的樱花树
2020/01/03 Python
利用Python脚本批量生成SQL语句
2020/03/04 Python
matplotlib 对坐标的控制,加图例注释的操作
2020/04/17 Python
加拿大的标志性百货公司:Hudson’s Bay(哈得逊湾)
2019/09/03 全球购物
亚洲领先的设计购物网站:Pinkoi
2020/11/26 全球购物
.TTL是什么?有什么用处,通常那些工具会用到它?(ping? traceroute? ifconfig? netstat?)
2016/05/09 面试题
工作失误检讨书范文大全
2014/01/13 职场文书
股票投资建议书
2014/05/19 职场文书
资产运营委托书范本
2014/10/16 职场文书
感谢师恩主题班会
2015/08/17 职场文书
当你找不到方向的时候,不妨读读刘备的一生
2019/08/05 职场文书