JavaScript中valueOf函数与toString方法深入理解


Posted in Javascript onDecember 02, 2012

JavaScript中valueOf函数方法是返回指定对象的原始值。使用方法:
object.valueOf( )object是必选项参数是任意固有 JScript 对象。
每个JavaScript固有对象的 valueOf 方法定义不同。

对象 返回值
Array 数组的元素被转换为字符串,这些字符串由逗号分隔,连接在一起。其操作与 Array.toString 和 Array.join 方法相同。
Boolean Boolean 值。
Date 存储的时间是从 1970 年 1 月 1 日午夜开始计的毫秒数 UTC。
Function 函数本身。
Number 数字值。
Object 对象本身。这是默认情况。
String 字符串值。

Math 和 Error 对象没有 valueOf 方法。

基本上,所有JS数据类型都拥有valueOf和toString这两个方法,null除外。它们俩解决javascript值运算与显示的问题。
JavaScript 的 valueOf() 方法
valueOf() 方法可返回 Boolean 对象的原始值。
用法booleanObject.valueOf(),返回值为booleanObject 的原始布尔值。如果调用该方法的对象不是 Boolean,则抛出异常 TypeError。

<script type="text/javascript"> 
var boo = new Boolean(false); 
document.write(boo.valueOf()); 
</script>

以上脚本会输出false。
JavaScript 的 toString() 方法
toString() 方法可把一个逻辑值转换为字符串,并返回结果。
用法 booleanObject.toString(),返回值根据原始布尔值或者 booleanObject 对象的值返回字符串 "true" 或 "false"。如果调用该方法的对象不是 Boolean,则抛出异常 TypeError。
在 Boolean 对象被用于字符串环境中时,此方法会被自动调用。
下面脚本将创建一个 Boolean 对象,并把它转换成字符串:
<script type="text/javascript"> 
var boo = new Boolean(true); 
document.write(boo.toString()); 
</script>

脚本输出:true。
先看一例
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方法。但如何区分什么情况下是调用了哪个方法呢,我们可以通过另一个方法测试一下。由于用到console.log,请在装有firebug的FF中实验!
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上阵了。对于那个奇怪的字符串拼接问题,可能是出于操作符上,翻开ECMA262-5 发现都有一个getValue操作。嗯,那么谜底应该是揭开了。重写会加大它们调用的优化高,而在有操作符的情况下,valueOf的优先级本来就比toString的高。
Javascript 相关文章推荐
js event事件的传递与冒泡处理
Dec 06 Javascript
人人网javascript面试题 可以提前实现下
Jan 05 Javascript
找出字符串中出现次数最多的字母和出现次数精简版
Nov 07 Javascript
JS控制一个DIV层在指定时间内消失的方法
Feb 17 Javascript
浅谈JSON和JSONP区别及jQuery的ajax jsonp的使用
Nov 23 Javascript
JS实现统计复选框选中个数并提示确定与取消的方法
Jul 01 Javascript
基于javascript实现最简单的选项卡切换效果
May 16 Javascript
JavaScript实现设计模式中的单例模式的一些技巧总结
May 17 Javascript
关于Angular2 + node接口调试的解决方案
May 28 Javascript
javascript性能优化之分时函数的介绍
Mar 28 Javascript
Nuxt.js实现校验访问浏览器类型的中间件
Aug 24 Javascript
JS+CSS实现3D切割轮播图
Mar 21 Javascript
json对象转字符串如何实现
Dec 02 #Javascript
javascript 构造函数强制调用经验总结
Dec 02 #Javascript
js精度溢出解决方案
Dec 02 #Javascript
JavaScript词法作用域与调用对象深入理解
Nov 29 #Javascript
浏览器加载、渲染和解析过程黑箱简析
Nov 29 #Javascript
javascript控制swfObject应用介绍
Nov 29 #Javascript
javascript 保存文件到本地实现方法
Nov 29 #Javascript
You might like
php自定义函数截取汉字长度
2014/05/15 PHP
支持生僻字且自动识别utf-8编码的php汉字转拼音类
2014/06/27 PHP
PHP封装分页函数实现文本分页和数字分页
2014/10/23 PHP
laravel框架模型中非静态方法也能静态调用的原理分析
2019/11/23 PHP
用javascript实现的激活输入框后隐藏初始内容
2007/06/29 Javascript
jQuery解决iframe高度自适应代码
2009/12/20 Javascript
javascript URL编码和解码使用说明
2010/04/12 Javascript
23个Javascript弹出窗口特效整理
2011/02/25 Javascript
javascript批量修改文件编码格式的方法
2015/01/27 Javascript
jQuery插件multiScroll实现全屏鼠标滚动切换页面特效
2015/04/12 Javascript
AngularJS页面访问时出现页面闪烁问题的解决
2016/03/06 Javascript
深入浅析JavaScript中的3DES
2016/08/24 Javascript
JavaScript实现时钟滴答声效果
2017/01/29 Javascript
jQuery Validate 无法验证 chosen-select元素的解决方法
2017/05/17 jQuery
前端常见跨域解决方案(全)
2017/09/19 Javascript
JS实现碰撞检测的方法分析
2018/01/19 Javascript
vue项目首屏打开速度慢的解决方法
2019/03/31 Javascript
解决vue初始化项目时,一直卡在Project description上的问题
2019/10/31 Javascript
浅谈webpack和webpack-cli模块源码分析
2020/01/19 Javascript
JS面向对象编程基础篇(一) 对象和构造函数实例详解
2020/03/03 Javascript
详细分析Node.js 模块系统
2020/06/28 Javascript
在python win系统下 打开TXT文件的实例
2018/04/29 Python
详解python校验SQL脚本命名规则
2019/03/22 Python
详解Python网络框架Django和Scrapy安装指南
2019/04/01 Python
Python使用sax模块解析XML文件示例
2019/04/04 Python
python如何支持并发方法详解
2020/07/25 Python
html5 初试 indexedDB(推荐)
2016/07/21 HTML / CSS
荷兰鞋子在线:Nelson Schoenen
2017/12/25 全球购物
优秀党员转正的自我评价
2013/10/06 职场文书
员工工作表扬信范文
2014/01/13 职场文书
母亲七十大寿答谢词
2014/01/18 职场文书
弘扬雷锋精神演讲稿
2014/05/10 职场文书
行政人事主管岗位职责
2015/04/11 职场文书
大学生党课感想
2015/08/11 职场文书
2016年4月份红领巾广播稿
2015/12/21 职场文书
Mybatis是这样防止sql注入的
2021/12/06 Java/Android