用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 相关文章推荐
Web层改进II-用xmlhttp 无声息提交复杂表单
Jan 22 Javascript
JQuery toggle使用分析
Nov 16 Javascript
jQuery动态添加 input type=file的实现代码
Jun 14 Javascript
jquery监听div内容的变化具体实现思路
Nov 04 Javascript
jquery跟js初始化加载的多种方法及区别介绍
Apr 02 Javascript
js绘制购物车抛物线动画
Nov 18 Javascript
微信小程序 教程之数据绑定
Oct 18 Javascript
解决给dom元素绑定click等事件无效问题的方法
Feb 17 Javascript
React Native悬浮按钮组件的示例代码
Apr 05 Javascript
说说node中的可读流和可写流的区别
Jun 01 Javascript
如何在VUE中使用vue-awesome-swiper
Jan 04 Vue.js
vue 递归组件的简单使用示例
Jan 14 Vue.js
使用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
apache rewrite_module模块使用教程
2008/01/10 PHP
PHP中的cookie不用刷新就生效的方法
2012/02/04 PHP
PHP判断JSON对象是否存在的方法(推荐)
2016/07/06 PHP
Yii框架参数化查询中IN查询只能查询一个的解决方法
2017/05/20 PHP
在laravel框架中实现封装公共方法全局调用
2019/10/14 PHP
用showModalDialog弹出页面后,提交表单总是弹出一个新窗口
2009/07/18 Javascript
javascript 面向对象继承
2009/11/26 Javascript
Javascript异步表单提交,图片上传,兼容异步模拟ajax技术
2010/05/10 Javascript
读jQuery之三(构建选择器)
2011/06/11 Javascript
使用angular写一个hello world
2015/01/23 Javascript
JQuery Mobile 弹出式登录框的实现方法
2016/05/28 Javascript
微信小程序  wx.request合法域名配置详解
2016/11/23 Javascript
Canvas 绘制粒子动画背景
2017/02/15 Javascript
angular2 ng build部署后base文件路径问题详细解答
2017/07/15 Javascript
Vue.js 实现微信公众号菜单编辑器功能(二)
2018/05/08 Javascript
Vue项目中配置pug解析支持
2019/05/10 Javascript
编写v-for循环的技巧汇总
2020/12/01 Javascript
python访问mysql数据库的实现方法(2则示例)
2016/01/06 Python
Python科学计算之NumPy入门教程
2017/01/15 Python
Python3实现的简单验证码识别功能示例
2018/05/02 Python
Python实现的从右到左字符串替换方法示例
2018/07/06 Python
Python unittest 简单实现参数化的方法
2018/11/30 Python
对python当中不在本路径的py文件的引用详解
2018/12/15 Python
python自定义线程池控制线程数量的示例
2019/02/22 Python
pycharm new project变成灰色的解决方法
2019/06/27 Python
在PyCharm的 Terminal(终端)切换Python版本的方法
2019/08/02 Python
python获取Pandas列名的几种方法
2019/08/07 Python
Python实现计算图像RGB均值方式
2020/06/04 Python
详解如何在PyCharm控制台中输出彩色文字和背景
2020/08/17 Python
Selenium 配置启动项参数的方法
2020/12/04 Python
采购部部长岗位职责
2014/02/06 职场文书
分居协议书范本
2014/11/03 职场文书
酒店员工辞职信范文
2015/02/28 职场文书
无婚姻登记记录证明
2015/06/18 职场文书
详解python网络进程
2021/06/15 Python
Sleuth+logback 设置traceid 及自定义信息方式
2021/07/26 Java/Android