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 相关文章推荐
Javascript 的addEventListener()及attachEvent()区别分析
May 21 Javascript
jQuery 开发者应该注意的9个错误
May 03 Javascript
一些常用弹出窗口/拖放/异步文件上传等实用代码
Jan 06 Javascript
修改file按钮的默认样式实现代码
Apr 23 Javascript
JavaScript基础之AJAX简单的小demo
Jan 29 Javascript
JS Testing Properties 判断属性是否在对象里的方法
Oct 01 Javascript
详解基于vue-cli优化的webpack配置
Nov 06 Javascript
简单两步使用node发送qq邮件的方法
Mar 01 Javascript
小程序封装路由文件和路由方法(5种全解析)
May 26 Javascript
vue动态循环出的多个select出现过的变为disabled(实例代码)
Nov 10 Javascript
一文秒懂JavaScript构造函数、实例、原型对象以及原型链
Aug 25 Javascript
vue 数据双向绑定的实现方法
Mar 04 Vue.js
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
骨王战斗力在公会成员中排不进前五,却当选了会长,原因竟是这样
2020/03/02 日漫
[原创]效率较高的php下读取文本文件的代码
2008/07/02 PHP
PHP中文件上传的一个问题
2010/09/04 PHP
浏览器无法运行JAVA脚本的解决方法
2008/01/09 Javascript
jQuery对象和DOM对象的相互转化实现代码
2010/03/02 Javascript
悄悄用脚本检查你访问过哪些网站的代码
2010/12/04 Javascript
使用apply方法实现javascript中的对象继承
2013/12/16 Javascript
文本框倒叙输入让输入框的焦点始终在最开始的位置
2014/09/01 Javascript
JQuery中两个ul标签的li互相移动实现方法
2015/05/18 Javascript
JavaScript中的Math.E属性使用详解
2015/06/12 Javascript
JavaScript实现的背景自动变色代码
2015/10/17 Javascript
浅谈javascript中replace()方法
2015/11/10 Javascript
javascript禁止超链接跳转的方法
2016/02/02 Javascript
jQuery插件ajaxFileUpload使用详解
2017/01/10 Javascript
js 作用域和变量详解
2017/02/16 Javascript
jQuery实现获取table中鼠标click点击位置行号与列号的方法
2017/10/09 jQuery
判断jQuery是否加载完成,没完成继续判断的解决方法
2017/12/06 jQuery
JavaScript实现一个简易的计算器实例代码
2018/05/10 Javascript
使用vue-cli脚手架工具搭建vue-webpack项目
2019/01/14 Javascript
在小程序中推送模板消息的实现方法
2019/07/22 Javascript
Python中的Numpy入门教程
2014/04/26 Python
在树莓派2或树莓派B+上安装Python和OpenCV的教程
2015/03/30 Python
Python re 模块findall() 函数返回值展现方式解析
2019/08/09 Python
python3.6中@property装饰器的使用方法示例
2019/08/17 Python
Tensorflow 使用pb文件保存(恢复)模型计算图和参数实例详解
2020/02/11 Python
在keras中model.fit_generator()和model.fit()的区别说明
2020/06/17 Python
Python爬虫获取op.gg英雄联盟英雄对位胜率的源码
2021/01/29 Python
eBay意大利购物网站:eBay.it
2019/09/04 全球购物
工业学校毕业生自荐书
2014/01/03 职场文书
服装创业计划书范文
2014/02/05 职场文书
重阳节活动总结
2014/08/27 职场文书
廉政教育的心得体会
2014/09/01 职场文书
学籍证明模板
2014/11/21 职场文书
asyncio异步编程之Task对象详解
2022/03/13 Python
Ruby序列化和持久化存储 Marshal和Pstore介绍
2022/04/18 Ruby
高通2023 年将发布高性能PC处理器
2022/04/29 数码科技