JavaScript中Object.prototype.toString方法的原理
在JavaScript中,想要判断某个对象值属于哪种内置类型,最靠谱的做法就是通过Object.prototype.toString方法.
<一>, ECMAScript 3
1. 在ES3中,Object.prototype.toString方法的规范如下:
15.2.4.2 Object.prototype.toString()
在toString方法被调用时,会执行下面的操作步骤:
1. 获取this对象的[[Class]]属性的值.
2. 计算出三个字符串"[object ", 第一步的操作结果Result(1), 以及 "]"连接后的新字符串.
3. 返回第二步的操作结果Result(2).
[[Class]]是一个内部属性,所有的对象(原生对象和宿主对象)都拥有该属性.在规范中,[[Class]]是这么定义的
备注: 然后给了一段解释
所有内置对象的[[Class]]属性的值是由本规范定义的.所有宿主对象的[[Class]]属性的值可以是任意值,甚至可以是内置对象使用过的[[Class]]属性的值.[[Class]]属性的值可以用来判断一个原生对象属于哪种内置类型.需要注意的是,除了通过Object.prototype.toString方法之外,本规范没有提供任何其他方式来让程序访问该属性的值(查看 15.2.4.2).
也就是说,把Object.prototype.toString方法返回的字符串,去掉前面固定的"[object "和后面固定的"]",就是内部属性[[class]]的值,也就达到了判断对象类型的目的.jQuery中的工具方法$.type(),就是干这个的.
在ES3中,规范文档并没有总结出[[class]]内部属性一共有几种,不过我们可以自己统计一下,原生对象的[[class]]内部属性的值一共有10种.分别是:"Array", "Boolean", "Date", "Error", "Function", "Math", "Number", "Object", "RegExp", "String".
<二>, ECMAScript 5
在ES5.1中,除了规范写的更详细一些以外,Object.prototype.toString方法和[[class]]内部属性的定义上也有一些变化,Object.prototype.toString方法的规范如下:
在toString方法被调用时,会执行下面的操作步骤:
如果this的值为undefined,则返回"[object Undefined]".
如果this的值为null,则返回"[object Null]".
让O成为调用ToObject(this)的结果.
让class成为O的内部属性[[Class]]的值.
返回三个字符串"[object ", class, 以及 "]"连接后的新字符串.
可以看出,比ES3多了1,2,3步.第1,2步属于新规则,比较特殊,因为"Undefined"和"Null"并不属于[[class]]属性的值,需要注意的是,这里和严格模式无关(大部分函数在严格模式下,this的值才会保持undefined或null,非严格模式下会自动成为全局对象).第3步并不算是新规则,因为在ES3的引擎中,也都会在这一步将三种原始值类型转换成对应的包装对象,只是规范中没写出来.ES5中,[[Class]]属性的解释更加详细:
所有内置对象的[[Class]]属性的值是由本规范定义的.所有宿主对象的[[Class]]属性的值可以是除了"Arguments", "Array", "Boolean", "Date", "Error", "Function", "JSON", "Math", "Number", "Object", "RegExp", "String"之外的的任何字符串.[[Class]]内部属性是引擎内部用来判断一个对象属于哪种类型的值的.需要注意的是,除了通过Object.prototype.toString方法之外,本规范没有提供任何其他方式来让程序访问该属性的值(查看 15.2.4.2).
和ES3对比一下,第一个差别就是[[class]]内部属性的值多了两种,成了12种,一种是arguments对象的[[class]]成了"Arguments",而不是以前的"Object",还有就是多个了全局对象JSON,它的[[class]]值为"JSON".第二个差别就是,宿主对象的[[class]]内部属性的值,不能和这12种值冲突,不过在支持ES3的浏览器中,貌似也没有发现哪些宿主对象故意使用那10个值.
<三>, ECMAScript 5
ES6中 @@toStringTag很容易改变Object.prototype.toString返回值
let obj = {}Object.defineProperty(obj, Symbol.toStringTag, {get: function() {return "newClass"} })console.log(Object.prototype.toString.call(obj)) // "[object newClass]"
<四>, 总结
如果我们要判断一个某个对象的内置类型,可以用如下函数
function getClass (a) {const str = Object.prototype.toString.call(a);return /^\[object (.*)\]$/.exec(str)[1].toLocaleUpperCase();
}
测试如下
function foo() {console.log(getClass(arguments)); // ARGUMENTS }foo();function* nav() {console.log(getClass(arguments)); // ARGUMENTSyield 1;yield 2;}let its = nav();its.next();console.log(getClass({})); // OBJECTconsole.log(getClass([])); // ARRAYconsole.log(getClass(1234)); // NUMBERconsole.log(getClass("wuhan")); // STRINGconsole.log(getClass(/^[a-z]+/gi)); // REGEXPconsole.log(getClass(true)); // BOOLEANconsole.log(getClass(new Date())); // DATEconsole.log(getClass(new Error())); // ERRORconsole.log(getClass(new Function())); // FUNCTIONconsole.log(getClass(Math)); // MATHconsole.log(getClass(null)); // NULLconsole.log(getClass(undefined)); // UNDEFINED
转载于:https://www.cnblogs.com/yyy6/p/9447322.html
JavaScript中Object.prototype.toString方法的原理相关推荐
- JavaScript:Object.prototype.toString方法的原理
在JavaScript中,想要判断某个对象值属于哪种内置类型,最靠谱的做法就是通过Object.prototype.toString方法. var arr = []; console.log(Obje ...
- 【javaScript】Object.prototype.toString.call() 、 instanceof 以及 Array.isArray() 区别与优化层面的比较
1. Object.prototype.toString.call() 每一个继承 Object 的对象都有 toString 方法,如果 toString 方法没有重写的话,会返回 [Object ...
- JavaScript:Object.prototype.toString进行数据类型判定
在JavaScript中,想要判断某个对象值属于哪种内置类型,最靠谱的做法就是通过Object.prototype.toString方法. var arr = []; console.log(Obje ...
- 由Object.prototype.toString.call( )引发关于toString( )方法的思考
引言 前端面试中有这么一道经典的问题,如何判断一个对象是否为数组? ES5提供了一个确定对象是否为数组的函数 Array.isArray(object); 复制代码 其中,object是必须的,表示要 ...
- 关于 Object.prototype.toString.call() 方法
Javascript中可通过typeof来获取对象的类型,但是对象如果是内置的继承Object的类型,typeof也只能返回object,不能获取对象的具体类型,如Date,Array,Boolean ...
- JS中的toString、Object.toString、Object.prototype.toString
不同类型值的toString方法: //Number const num = 123; num.toString(); // '123' (123).toString(); // '123' 整数必须 ...
- php中this的使用技巧,JavaScript中this关键字使用方法详解
JavaScript中this关键字使用方法详解 在面向对象编程语言中,对于this关键字我们是非常熟悉的.比如C++.C#和Java等都提供了这个关键字,虽然在开始学习的时候觉得比较难,但只要理解了 ...
- JavaScript中Object的总结
基于原型继承,动态对象扩展,闭包,JavaScript已经成为当今世界上最灵活和富有表现力的编程语言之一. 这里有一个很重要的概念需要特别指出:在JavaScript中,包括所有的函数,数组,键值对和 ...
- Object.prototype.toString.call()检测
在日常开发中,我们经常需要判断某个对象是否是数组类型的,在js中检测对象类型的常见的方法有几种: 1.typeof操作符.对于Function.String.Number.Undefined这几种类型 ...
最新文章
- multisim页面不够大_观赏变出售 捡漏钱不够
- <java并发编程实践>读书笔记三
- StartService返回2的解决方法
- 上传图片被防火墙拦截_Murus Pro Suite——防火墙软件
- ant app 心电监测_医疗级心电健康手表,随时随地监测你的健康,心电手表H1手表评测...
- srs 服务关闭命令_【经验总结】如何做到网络版工作站与服务器时间同步?
- Redis都有哪些监控指标,看完你就懂了!
- C++实现分割读取txt文件以及对齐打印设置
- 【POJ2259】Team Queue(队列,模拟)
- Java logging整理
- JAVA入门到精通-第64讲-sql server备份恢复
- 3. jQuery 选择器
- vc2008工程转vc2005
- 分分钟搞定 OpenV2X 开发环境
- mysql排列组合实现_排列组合的实现
- 如何自定义 GNOME 3 桌面?
- 祝老婆生日快乐(无内容)
- ansys经典界面分析工字钢_工字钢_ANSYS实例分析72道(含结果)
- ffmpeg将gif转换成mp4
- Wio Terminal 从网络获取天气数据
热门文章
- linux shell 变量减法_第四章 shell和环境变量
- 百度java验证码不显示不出来,Java-使用百度链接时,遇到无法弹出用户登录框的问题...
- matlab消去前一个图,各位matlab高手,如何从2个3元方程中消去一个变量,然后做3维图形~...
- Java开发面试题,Spring面试题整理(1)
- 【PAT (Advanced Level) Practice】1005 Spell It Right (20 分)
- 【深度学习】论文EMO单眼识别分析
- java聊天程序_急需一个用java 语言写的聊天程序
- html自定义标签提示,用简单的jquery+CSS创建自定义的a标签title提示tooltip_HTML/Xhtml_网页制作...
- 企业网络推广有效收录一定会带来排名?企业网络推广专员怎么说?
- 网站如何布局才能更利于提升用户体验?