一日一练-JS toString 和valueOf 方法的联系与区别
子曰:类型转换中toString 和valueOf 的联系与区别分析
首先是看看ES5 的规范是如何进行说明的
在这里有几个基础知识点需要了解一下:
[[Class]]
[[Class]]属于Object 的内部属性,值的类型返回为String,其作用是,说明规范定义的对象分类的一个字符串值。
ES5 规范的每种内置对象都定义了[[Class]]内部属性值。宿主对象的[[Class]]内部属性值可以是除了“Arguments”、 “Array”、 “Boolean”、 “Date”、 “Error”、 “Function”、 “JSON”、 “Math”、 “Number”、 “Object”、 “RegExp”、 “String” 的任意字符串。[[Class]]内部属性的值用于内部区分对象的种类。注,本规范中除了通过Object.prototype.toString没有提供任何手段使程序访问此值。
摘自ES5 类型
[[PrimitiveValue]]
[[PrimitiveValue]]属于只在某些对象中定义的内部属性,其值的类型范围为原始类型,作用是说明与此对象的内部状态信息关联。对于标准内置对象只能用 Boolean、Date、Number、String 对象实现[[PrimitiveValue]]。
摘自ES5 类型
ToObject
ToObject抽象操作根据下表将其参数转换为对象类型的值:
| 输入类型 | 结果 |
|---|---|
| 未定义 | 抛出TypeError 异常。 |
| 空值 | 抛出TypeError 异常。 |
| 布尔值 | 创建一个新的Boolean 对象,其[[PrimitiveValue]] 属性被设为该参数的值。 |
| 数值 | 创建一个新的Number 对象,其[[PrimitiveValue]] 属性被设为该参数的值。 |
| 字符串 | 创建一个新的String 对象,其[[PrimitiveValue]] 属性被设为该参数的值。 |
| 对象 | 结果是输入的参数(不转换) |
Object.prototype.toString()
当调用toString 方法,采用如下步骤:
- 如果
this的值是undefined, 返回 [object Undefined]。 - 如果
this的值是null, 返回 [object Null]。 - 令O 为以
this作为参数调用ToObject的结果。 - 令
class为O 的[[Class]]内部属性的值。 - 返回三个字符串"[Object "、
class和"]" 连起来的字符串。
Object.prototype.valueOf()
当调用valueOf 方法,采用如下步骤:
- 令O 为以
this作为参数调用ToObject的结果。 - 如果O 是以宿主对象15.2.2.1作为参数调用
Object构造器的结果,则
2.1. 返回O 或返回先前传递给构造器的原宿主对象。返回的具体结果是由实现定义的。 - 返回O。
toString() 和valueOf()
所有对象继承了两个转换方法。
toString()
作用是返回一个反映这个对象的字符串。默认的toString()方法返回值
({x:1, y:2}).toString() // => "[object Object]"
1.1. 数组类(Array class)
将每个数组元素转换为一个字符串,并在元素之间添加逗号后合并结果字符串。
js [1,2,3].toString() // => "1,2,3"
1.2. 函数类(Function class)
返回这个函数的实现定义的表示方法。实际上,这里的实现方式是通常是将用户定义的函数转换为JavaScript 源代码字符串。
js (function(x) { f(x) }).toString() // => "function(x) {\n f(x) \n }"
1.3. 日期类(Date class)
返回一个可读的(意指可以通过JavaScript 的方法过了并再做封装)日期和时间字符串。
js new Date().toString() // => "Tue Apr 24 2018 09:43:31 GMT+0800 (中国标准时间)"
1.4. RegExp 类(RegExp class)
将RegExp 对象转换为表示正则表达式直接量的字符串。
js /\d+/g.toString() // => "/\\d+/g"
2. valueOf()
这个方法的任务并未详细定义:如果存在任意原始值,它就默认将对象转换为表示它的原始值。对象是复合值,而且诶额大多数对象无法真正表示为一个原始值,因此默认的valueOf() 方法简单地返回对象本身,而不是返回一个原始值。
2.1. 数组、函数和正则表达式简单地继承了这个默认方法,调用这些类型的实例的valueOf() 方法只是简单返回对象本身。
2.2. 日期类定义的valueOf() 方法会返回它额一个内部表示:1970年1月1日以来的毫秒数。
var d = new Date(2018,4,1) // => 2018年5月1日
d.valueOf() // => 1525104000000
参考自《JavaScript 权威指南(第6版)(中文版)》第3 章 类型、值和变量 中的3.8 类型转换
对象转换为原始值
- 对象到布尔值的转换:
所有对象(包括数值和函数)都转换为true。对于包装函数亦是如此:new Boolean(false)是一个对象而不是原始值,它将转化为true - 对象到字符串的转换:
2.1. 如果对象具有toString()方法,则调用这个方法。如果它返回一个原始值,JavaScript 将原始值转换为字符串(如果它本身不是字符串的话),并返回这个字符串的结果。
2.2. 如果对象没有toString()方法, 或者这个方法并不返回一个原始值,那么JavaScript 会调用valueOf()方法。如果存在这个方法,则JavaScript 调用它。如果返回值是原始值,JavaScript 将这个值转换为字符串(如果本身不是字符串的话),并返回这个字符串的结果。
2.3. 否则,JavaScript 无法从toString()或valueOf()获得一个原始值,因此这时它将抛出一个类型错误异常。 - 对象到数字的转换:
3.1. 如果对象具有valueOf()方法,后者返回一个原始值,则JavaScript 将这个原始值转换为数字(如果需要的话)并返回这个数字。
3.2. 否则,如果对象具有toString()方法,后者返回一个原始值,则JavaScript 将其转换并返回。对象的toString()方法返回一个字符串直接量(这里的原始值),JavaScript 将这个字符串转换为数字类型,并返回这数字。
3.3. 否则,JavaScript 抛出一个类型错误异常。
参考自《JavaScript 权威指南(第6版)(中文版)》第3 章 类型、值和变量 中的3.8 类型转换
实例讲解
- 空数组会被转换为数字0,具有单个元素的数组同样会转换为一个数组。
Number([]) // => 0
Number(['1234']) // => 1234
数组继承了默认的valueOf() 方法,这个方法返回一个对象而不是一个原始值,因此,数组到数字的转换则调用toString() 方法。空数组转换为空字符串,空字符串转换成数字0.
// [] => '' => 0
[].valueOf() // => []
[].toString() // => ''
'' // => 0
含有一个元素的数组转换为字符串的结果和这个元素转换字符串的结果一样。如果数组只包含一个数字元素,这个数字转换为字符串,再转换会数字。
[1].valueOf() // => [1]
[1].toString() // => "1"
"1" // => 1
+运算符可以进行数字加法和字符串连接操作。
如果它的其中一个操作数是对象,则JavaScript 将使用特殊的方法将对象转换为原始值,而不是执行对象到方法的转换。
这种特殊方式是指:通过valueOf()或者toString()返回的原始值将被直接使用,而不会被强制转换为数字或字符串。
+、==、!=和关系运算符也会做对象到原始值的转换,但要除去日期对象的特殊情形:任何对象都会首先尝试调用valueOf(),然后调用toString()。不管得到的原始值是否直接使用,它都不会进一步被转换为数字或字符串。
参考自《JavaScript 权威指南(第6版)(中文版)》第3 章 类型、值和变量 中的3.8 类型转换
一日一练-JS toString 和valueOf 方法的联系与区别的更多相关文章
- 简单说 JavaScript中的tostring( ) 与 valueOf( )方法
说明 所有的对象都继承有toString() 和 valueOf() 方法,对象到字符串,对象到数字的转换,会通过调用待转换对象的这两个方法中的一个来完成. 解释 toString( )方法的作用是: ...
- JavaScript引用类型之Array数组的toString()和valueof()方法的区别
一.转换方法 1.在JavaScript中几乎所有对象都具有toLocaleString().toString和valueof()方法,因为,所有的对象都继承自Object,而前面所说的方法都是Obj ...
- 区分javascript中的toString(),toLocaleString(),valueOf()方法
首先我们随意创建一个对象,这很简单,打开FF浏览器的Firebug切换到控制台或者打开webkit浏览器的审查元素功能. 输入以下内容: var obj1=[1,2,3,4,5] var obj2=[ ...
- 《JS权威指南学习总结--toString()和valueOf()方法》
方法要点: 一.toString()方法 1.主要用于Array.Boolean.Date.Error.Function.Number等对象转化为字符串形式. 数组类的toSting()方法 ...
- js中toString和valueOf方法的区别
toString 方法 返回对象的字符串表示形式. 语法:objectname.toString([radix]) objectname 必需.要为其搜索字符串表示形式的对象. radix 可选.为将 ...
- JS中的toString()和valueOf()方法
1.toString()方法:主要用于Array.Boolean.Date.Error.Function.Number等对象转化为字符串形式.日期类的toString()方法返回一个可读的日期和字符串 ...
- JavaScript的toString()和valueof()方法
toString()方法: 函数:函数 (function(){}).toString(); //返回"function(){}" typeof((function(){}).to ...
- Java中区别.toString() ,(String),valueOf()方法
在java项目的实际开发和应用中,常常需要用到将对象转为String这一基本功能.本文将对常用的转换方法进行一个总结.常用的方法有Object.toString(),(String)要转换的对象,St ...
- javascript中toString和valueOf方法的区别
toString():将对象转为字符串 valueOf():获取对象的原始值, 1.针对基本类型的变量:如在string,number,boolean类型的变量上调用这两个方法时,直接返回原始值,即变 ...
随机推荐
- 04_Linux目录文件操作命令1(mv ls cd...)_我的Linux之路
上一节已经给大家讲了Linux的目录结构,相信大家已经对Linux的整个目录结构有所了解 现实中,服务器(包含Linux,Unix,windows server)一般都摆放在机房里,因为一个机房摆放了 ...
- 微信开发之SVN提交代码与FTP同步到apache的根目录
SVN是协同开发的,版本控制器,就是几个人同时开发,可以提交代码到SVN服务器,这样就可以协同开发,一般是早上上班首先更新下代码,然后自己修改代码 工作一天之后,修改代码之后,下班之前,更新代码,然后 ...
- node框架koa
node的两大常见web服务器框架有express和koa,之前已经介绍过express了现在来介绍下koa吧~ koa也是express团队的出品,意在利用es7新出的async来告别"回 ...
- c#动态加载卸载DLL
前段时间工作的时候遇到一个问题.就是需要每次启动程序的时候动态替换掉某个dll,所以就百度了这方面的资料.这次记录下来让自己以后可以看. 根据自己的理解,动态卸载dll需要有以下条件: 1:dll在加 ...
- EasyUI combobox下拉多选框的实现
combobox实现下拉列表多选, 效果如下
- VCS使用学习笔记(1)——Verilog相关的仿真知识
本文主要学习Verilog的仿真特性,以及仿真器对Verilog的处理,算是对Verilog知识的增量学习.本文内容与我的另一篇博文(http://www.cnblogs.com/IClearner/ ...
- python基础(常用内容)
python基础(常用内容) 机器数: 一个数在计算机中的二进制表示形式就是机器数. 例如: +3用机器数表示就用<00000011>表示 -3用机器数表示就用<10000011&g ...
- PyQuery用法详解
PyQuery是强大而又灵活的网页解析库,如果你觉得正则写起来太麻烦,如果你觉得BeautifulSoup语法太难记,如果你熟悉jQuery的语法 那么,PyQuery就是你绝佳的选择. 一.初始化方 ...
- Spring源码分析:Spring IOC容器初始化
概述: Spring 对于Java 开发来说,以及算得上非常基础并且核心的框架了,在有一定开发经验后,阅读源码能更好的提高我们的编码能力并且让我们对其更加理解.俗话说知己知彼,百战不殆.当你对Spri ...
- SSH端口转发(本地转发、远程转发、动态转发)
SSH端口转发 一:什么是端口转发? SSH 会自动加密和解密所有SSH 客户端与服务端之间的网络数据.但是,SSH 还能够将其他TCP 端口的网络数据通过SSH 链接来转发,并且自动提供 ...