JS中 toString() & valueOf()
数据的转换
所有对象继承了两个转换方法:
第一个是toString(),它的作用是返回一个反映这个对象的字符串
第二个是valueOf(),它的作用是返回它相应的原始值
toString()
toString()可以看做是把一个数据转换成了相应字符串的形式,安照这个转换规则中

使用样例:
//返回相应的字符串
console.log(
({x:1,
y:1
}).toString() ); // [object Object]
console.log([1,2,3].toString()); // 1,2,3
console.log((function(x){f(x); }).toString()); //function (x){f(x); }
console.log(/\d+/g.toString()); // /\d+/g
console.log(new Date(2015,4,4).toString()); // Mon May 04 2015 00:00:00 GMT+0800 console.log(new Date(2015,4,4).valueOf()); // 1430668800000
valueOf()
每个JavaScript固有对象的 valueOf 方法定义不同。
| 对象 | 返回值 |
| Array | 数组的元素被转换为字符串,这些字符串由逗号分隔,连接在一起。其操作与 Array.toString 和 Array.join 方法相同。 |
| Boolean | Boolean 值。 |
| Date | 存储的时间是从 1970 年 1 月 1 日午夜开始计的毫秒数 UTC。 |
| Function | 函数本身。 |
| Number | 数字值。 |
| Object | 对象本身。这是默认情况。 |
| String | 字符串值。 |
Math 和 Error 对象没有 valueOf 方法。
------------------------------------------------------------------------------------------------------------------------------
一般来说,对象到字符串的转换经过了如下步骤:
1.如果对象具有toString()方法,则调用这个方法。如果它返回一个原始值,js将这个值转换成字符串,并返还这个字符串结果。
2.如果对象没有toString()方法,或者这个方法并不返回一个原始值,那么js将调用valueOf()方法。
3.否则,js无法从toString()或者valueOf()获得一个原始值,因此这时它将抛出一个类型错误异常。
一般来说,对象到数字的转换过程中,js做了同样类似的事情,但这里它会首先尝试使用valueOf()方法:
1.如果对象具有valueOf()方法,后者返回一个原始值,则js将这个原始值转换成数字,并返回这个数字。
2.否则,如果对象具有toString()方法,后者返回一个原始值,则js将转换并返回。
(首先js转换成相应的字符串原始值,再继续将这个原始值转换成相应的数字类型,再返回数字)
3.否则,js抛出一个类型错误异常。
对象通过toString或valueOf方法转换为原始值,JS语言核心的内置类首先尝试使用valueOf(),再尝试使用toString()
一个小李子
“1” == true;
将返回true,转换形式是:true首先转换为1,然后再执行比较。接下来字符串“1”也转换成了数字1,相等,所以返回true
另外如:
var str = new String('hello,world');
console.log(typeof str); //'object'
console.log(typeof str.valueOf()); //'string'
对于所有非日期对象来说,对象到原始值的转换基本上是对象到数字的转换
(首先调用valueOf,但日期对象则使用对象到字符串的转换模式,但这种转换只执行一次就立即被使用,不会像上面所说的那般 先转成字符串再转成相应的数字类型)
比如说,js中“+"运算符可以进行数学加法和字符串连接操作。
如果他它的其中一个操作数是对象,则js将使用特殊的方法将对象转换成原始值,而不是使用其他算术运算符的方法执行对象到数字的转换,”==“运算符类似
和”==“一样,”<"与其他运算符也会做对象到原始值的转换,但要出去日期对象的特殊情形
“-“减号运算符把两个操作数都转换成数字
比如:
var now = new Date();
console.log(now); // Date {Sat Apr 04 2015 13:21:08 GMT+0800}
console.log(typeof (now+1)); //string
console.log((now+1)); //Sat Apr 04 2015 13:21:08 GMT+08001
console.log(typeof (now-1)); //number
console.log((now-1)); //
console.log(now == now.toString()); //true
console.log(now > now -1); //true
var date = new Date();
var date_string = date.toString();
var date_value = date.valueOf();
alert(date == date_string); //true
alert(date == date_value); //false
--------------------------------------------------------------------------------------------------------------------------------
更详细了使用例子:
(摘自:http://www.jb51.net/article/32327.htm)
var aaa = {
i: 10,
valueOf: function() { return this.i+30; },
toString: function() { return this.valueOf()+10; }
}
alert(aaa > 20); // true
alert(+aaa); // 40
alert(aaa); // 50
之所以有这样的结果,因为它们偷偷地调用valueOf或toString方法。更进一步测试
var bbb = {
i: 10,
toString: function() {
console.log('toString');
return this.i;
},
valueOf: function() {
console.log('valueOf');
return this.i;
}
}
alert(bbb);// 10 toString
alert(+bbb); // 10 valueOf
alert(''+bbb); // 10 valueOf
alert(String(bbb)); // 10 toString
alert(Number(bbb)); // 10 valueOf
alert(bbb == '10'); // true valueOf
alert(bbb === '10'); // false
乍一看结果,大抵给人的感觉是,如果转换为字符串时调用toString方法,如果是转换为数值时则调用valueOf方法,但其中有两个很不和谐。
一个是alert(''+bbb),字符串合拼应该是调用toString方法……另一个我们暂时可以理解为===操作符不进行隐式转换,因此不调用它们。
为了追究真相,我们需要更严谨的实验。
var aa = {
i: 10,
toString: function() {
console.log('toString');
return this.i;
}
}
alert(aa);// 10 toString
alert(+aa); // 10 toString
alert(''+aa); // 10 toString
alert(String(aa)); // 10 toString
alert(Number(aa)); // 10 toString
alert(aa == '10'); // true toString
再看valueOf。
var bb = {
i: 10,
valueOf: function() {
console.log('valueOf');
return this.i;
}
}
alert(bb);// [object Object]
alert(+bb); // 10 valueOf
alert(''+bb); // 10 valueOf
alert(String(bb)); // [object Object]
alert(Number(bb)); // 10 valueOf
alert(bb == '10'); // true valueOf
发现有点不同吧?!它没有像上面toString那样统一规整。对于那个[object Object],我估计是从Object那里继承过来的,我们再去掉它看看。
Object.prototype.toString = null;
var cc = {
i: 10,
valueOf: function() {
console.log('valueOf');
return this.i;
}
}
alert(cc);// 10 valueOf
alert(+cc); // 10 valueOf
alert(''+cc); // 10 valueOf
alert(String(cc)); // 10 valueOf
alert(Number(cc)); // 10 valueOf
alert(cc == '10'); // true valueOf
总结起来就是 如果只重写了toString,对象转换时会无视valueOf的存在来进行转换。
但是,如果只重写了valueOf方法,在要转换为字符串的时候会优先考虑valueOf方法。在不能调用toString的情况下,只能让valueOf上阵了
JS中 toString() & valueOf()的更多相关文章
- js中的valueOf与toString
所有对象继承了两个转换方法: 第一个是toString(),它的作用是返回一个反映这个对象的字符串 第二个是valueOf(),它的作用是返回它相应的原始值 一般来说,对象到字符串的转换经过了如下步骤 ...
- js中toString和valueOf方法的区别
toString 方法 返回对象的字符串表示形式. 语法:objectname.toString([radix]) objectname 必需.要为其搜索字符串表示形式的对象. radix 可选.为将 ...
- JS中toString()、toLocaleString()、valueOf()的区别
前言 Array.Boolean.Date.Number等对象都具有 toString().toLocaleString().valueOf()三个方法,那这三个方法有什么区别? 一.JS Array ...
- js 中 toString( ) 和valueOf( )
1.toString()方法:主要用于Array.Boolean.Date.Error.Function.Number等对象转化为字符串形式.日期类的toString()方法返回一个可读的日期和字符串 ...
- js中.toString()和String()的一丢丢区别
1..toString()可以将所有的的数据都转换为字符串,但是要排除null 和 undefined 例如将false转为字符串类型 <script> var str = false ...
- js引用类型之valueof和tostring(三)
一.摘要: <javascript高级程序设计第三版>一书中单独有一章对js的引用类型(Object.Array.RegExp.Function:基本包装类型:Boolean.Number ...
- 深入理解Javascript中的valueOf与toString
基本上,javascript中所有数据类型都拥有valueOf和toString这两个方法,null除外.它们俩解决javascript值运算与显示的问题,本文将详细介绍,有需要的朋友可以参考下. t ...
- js中的tostring()方法
http://blog.sina.com.cn/s/blog_85c1dc100101bxgg.html js中的tostring()方法 (2013-11-12 11:07:43) 转载▼ 标签: ...
- JS中令人发指的valueOf方法介绍
彭老湿近期月报里提到了valueOf方法,兴致来了翻了下ECMA5里关于valueOf方法的介绍,如下: 15.2.4.4 Object.prototype.valueOf ( ) When the ...
随机推荐
- error while loading shared libraries: /usr/lib64/libc.so.6: invalid ELF header
在安装一个程序的时候提示libc.so.6过旧,但是查看libc.so的版本是最新的,于是尝试使用尝试软链接 ln -s /usr/lib64/libc.so /usr/lib64/libc.so. ...
- 【linux】文件隐藏属性
这些隐藏的属性确实对于系统有很大的帮助的- 尤其是在系统安全 (Security) 上面,重要的紧呢!不过要先强调的是,底下的chattr指令只能在Ext2/Ext3的文件系统上面生效, 其他 ...
- android实现qq邮箱多个图标效果
前几天,蛋疼的技术主管非要实现类似装一个qq邮箱,然后能够使用qq邮箱日历的那么一个东西.相当于一个应用生成两个图标,可是不同的是点击不同的图标能够进入不同的应用,例如以下图的效果. 这效果百度了一天 ...
- Maven - 项目结构
一个基础的Maven Java项目结构图如下所示: Project Name |__________ pom.xml |__________ src | |__ ...
- 小米2成功使用google组件的办法(为了coc游戏能登录google账户)
1) 小米商店里下一个 “谷歌应用下载器”2) 用"谷歌应用下载器"安装相应的服务和应用(跟着提示把所有的服务都更新到最新版本就可以了,第3和第4可以不做)3) 小米商店里下一个 ...
- mysql性能瓶颈分析、性能指标、指标搜集方法与性能分析调优工具
本文主要讲解mysql的性能瓶颈分析.性能指标.性能指标信息的搜集工具与方法.分析调优工具的使用. 文章尚未完成. 性能瓶颈: 慢.写速度比读速度慢很多 主要的性能指标: 访问频度, 并发连接量, ...
- 转:Android开发之旅:环境搭建及HelloWorld
http://www.cnblogs.com/skynet/archive/2010/04/12/1709892.html 引言 本系列适合0基础的人员,因为我就是从0开始的,此系列记录我步入Andr ...
- Centos 6.5 下安装socket5代理
---恢复内容开始--- 1. 安装 先安装依赖库 yum -y install gcc gcc-c++ automake make pam-devel openldap-devel cyrus-sa ...
- algo_预备
章 C + +程序设计 大家好!现在我们将要开始一个穿越" 数据结构.算法和程序" 这个抽象世界的特殊旅程,以解决现实生活中的许多难题.在程序开发过程中通常需要做到如下两点:一是高 ...
- c#上iOS apns p12文件制作记录
1.在桌面上建一个"apns_p12"文件夹,所有的保存和生成文件都放在这里 2.从钥匙串中生成CertificateSigningRequest.certSigningReque ...