用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 相关文章推荐
腾讯的ip接口 方便获取当前用户的ip地理位置
Nov 25 Javascript
原生javascript获取元素样式属性值的方法
Dec 25 Javascript
ExtJS4 表格的嵌套 rowExpander应用
May 02 Javascript
jQuery统计上传文件大小的方法
Jan 24 Javascript
JavaScript将XML转成JSON的方法
Mar 12 Javascript
JQuery中DOM加载与事件执行实例分析
Jun 13 Javascript
详解javascript事件冒泡
Jan 09 Javascript
原生JS实现平滑回到顶部组件
Mar 16 Javascript
15款最好的Bootstrap在线编辑器
Aug 03 Javascript
原生js仿jquery一些常用方法(必看篇)
Sep 20 Javascript
Javascript中toFixed计算错误(依赖银行家舍入法的缺陷)解决方法
Aug 22 Javascript
VUEX采坑之路之获取不到$store的解决方法
Nov 08 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/08 日漫
利用discuz自带通行证整合dedecms的方法以及文件下载
2007/03/06 PHP
PHP的Yii框架中使用数据库的配置和SQL操作实例教程
2016/03/17 PHP
PHP遍历目录文件的常用方法小结
2017/02/03 PHP
PHP生成短网址的思路以及实现方法的详解
2019/03/25 PHP
PHP7引入的"??"和"?:"的区别讲解
2019/04/08 PHP
JS实现self的resend
2010/07/22 Javascript
JQuery加载图片自适应固定大小的DIV
2013/09/12 Javascript
javascript实现可键盘控制的抽奖系统
2016/03/10 Javascript
jQuery实现日期联动效果实例
2016/07/26 Javascript
jQuery遍历节点方法汇总(推荐)
2017/05/13 jQuery
详解vue2.0脚手架的webpack 配置文件分析
2017/05/27 Javascript
angular bootstrap timepicker TypeError提示怎么办
2017/06/13 Javascript
NodeJS收发GET和POST请求的示例代码
2017/08/25 NodeJs
angular.extend方法的具体使用
2017/09/14 Javascript
CheckBox多选取值及判断CheckBox选中是否为空的实例
2017/10/31 Javascript
微信小程序中实现手指缩放图片的示例代码
2018/03/13 Javascript
vuex state中的数组变化监听实例
2019/11/06 Javascript
Vue项目开发常见问题和解决方案总结
2020/09/11 Javascript
[05:13]2018DOTA2亚洲邀请赛主赛事第二日战况回顾 LGD、VG双雄携手晋级
2018/04/05 DOTA
[08:40]Navi Vs Newbee
2018/06/07 DOTA
仅用50行代码实现一个Python编写的计算器的教程
2015/04/17 Python
Python numpy 点数组去重的实例
2018/04/18 Python
python模糊图片过滤的方法
2018/12/14 Python
python代码实现猜拳小游戏
2020/11/30 Python
能否解释一下XSS cookie盗窃是什么意思
2012/06/02 面试题
借款协议书
2014/04/12 职场文书
演讲比赛策划方案
2014/06/11 职场文书
英语教师求职信
2014/06/16 职场文书
购房委托书范本
2014/09/18 职场文书
学校捐款活动总结
2015/05/09 职场文书
2016年党风廉政建设承诺书
2016/03/25 职场文书
详解Mysql 函数调用优化
2021/04/07 MySQL
Python Django ORM连表正反操作技巧
2021/06/13 Python
python编程实现清理微信重复缓存文件
2021/11/01 Python
IIS服务器中设置HTTP重定向访问HTTPS
2022/04/29 Servers