用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在IE和Firefox(火狐)的不兼容问题解决方法小结
Apr 13 Javascript
详谈 Jquery Ajax异步处理Json数据.
Sep 09 Javascript
JavaScript NaN和Infinity特殊值 [译]
Sep 20 Javascript
js螺旋动画效果的具体实例
Nov 15 Javascript
怎么选择Javascript框架(Javascript Framework)
Nov 22 Javascript
深入理解Javascript中的valueOf与toString
Jan 04 Javascript
JS常见算法详解
Feb 28 Javascript
JS闭包的几种常见形式实例详解
Sep 16 Javascript
jQuery实现页码跳转式动态数据分页
Dec 31 jQuery
vue中子组件调用兄弟组件方法
Jul 06 Javascript
Node.js + express实现上传大文件的方法分析【图片、文本文件】
Mar 14 Javascript
Vue + iView实现Excel上传功能的完整代码
Jun 22 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
php使用array_rand()函数从数组中随机选择一个或多个元素
2014/04/28 PHP
php5.3提示Function ereg() is deprecated Error问题解决方法
2014/11/12 PHP
PHP实现JS中escape与unescape的方法
2016/07/11 PHP
php5与php7的区别点总结
2019/10/11 PHP
JavaScript入门教程(12) js对象化编程
2009/01/31 Javascript
js 火狐下取本地路径实现思路
2013/04/02 Javascript
js取消单选按钮选中并判断对象是否为空
2013/11/14 Javascript
jQuery实现的多选框多级联动插件
2014/05/02 Javascript
js实现回放拖拽轨迹从过程上进行分析
2014/06/26 Javascript
Node.js重新刷新session过期时间的方法
2016/02/04 Javascript
简单的jQuery banner图片轮播实例代码
2016/03/04 Javascript
Javascript中的几种继承方式对比分析
2016/03/22 Javascript
js中判断变量类型函数typeof的用法总结
2016/08/09 Javascript
使用sessionStorage解决vuex在页面刷新后数据被清除的问题
2018/04/13 Javascript
vue-cli3.0+element-ui上传组件el-upload的使用
2018/12/03 Javascript
jQuery实现的网站banner图片无缝轮播效果完整实例
2019/01/28 jQuery
详解关于表格合并span-method方法的补充(表格数据由后台动态返回)
2019/05/21 Javascript
使用vue自定义指令开发表单验证插件validate.js
2019/05/23 Javascript
浅谈vue3中effect与computed的亲密关系
2019/10/10 Javascript
在Django的模型中添加自定义方法的示例
2015/07/21 Python
python调用xlsxwriter创建xlsx的方法
2018/05/03 Python
Django中使用第三方登录的示例代码
2018/08/20 Python
Python并行分布式框架Celery详解
2018/10/15 Python
Python之inspect模块实现获取加载模块路径的方法
2018/10/16 Python
基于python实现的百度音乐下载器python pyqt改进版(附代码)
2019/08/05 Python
Python pip配置国内源的方法
2020/02/14 Python
Python日志logging模块功能与用法详解
2020/04/09 Python
详解Python遍历列表时删除元素的正确做法
2021/01/07 Python
总经理驾驶员岗位职责
2013/12/04 职场文书
小学端午节活动方案
2014/03/13 职场文书
高中教师评语大全
2014/04/25 职场文书
知识改变命运演讲稿
2014/05/21 职场文书
画展邀请函
2015/01/31 职场文书
2015年电气技术员工作总结
2015/07/24 职场文书
2016年学习雷锋精神广播稿
2015/12/17 职场文书
mysql查询的控制语句图文详解
2021/04/11 MySQL