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进阶教程(第四课第一部分)
Apr 05 Javascript
Prototype String对象 学习
Jul 19 Javascript
ASP.NET jQuery 实例14 在ASP.NET form中校验时间范围
Feb 03 Javascript
jquery中的事件处理详细介绍
Jun 24 Javascript
js仿百度贴吧验证码特效实例代码
Jan 16 Javascript
JavaScript利用构造函数和原型的方式模拟C#类的功能
Mar 06 Javascript
jquery表单验证需要做些什么
Nov 17 Javascript
jQuery插件FusionCharts实现的2D面积图效果示例【附demo源码下载】
Mar 06 Javascript
使用Vue完成一个简单的todolist的方法
Dec 01 Javascript
10 种最常见的 Javascript 错误(频率最高)
Feb 08 Javascript
关于Webpack dev server热加载失败的解决方法
Feb 22 Javascript
Node Mongoose用法详解【Mongoose使用、Schema、对象、model文档等】
May 13 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生成指定随机字符串的简单实现方法
2015/04/01 PHP
定位地理位置PHP判断员工打卡签到经纬度是否在打卡之内
2019/05/23 PHP
Ext对基本类型的扩展 ext,extjs,format
2010/12/25 Javascript
深入理解javascript中defer的作用
2013/12/11 Javascript
简单的jquery左侧导航栏和页面选中效果
2014/08/21 Javascript
JavaScript针对网页节点的增删改查用法实例
2015/02/02 Javascript
jQuery实现iframe父窗体和子窗体的相互调用
2016/06/17 Javascript
AngularJS实现星星等级评分功能
2016/09/24 Javascript
jQuery视差滚动效果网页实现方法经验总结
2016/09/29 Javascript
一个炫酷的Bootstrap导航菜单
2016/12/28 Javascript
JavaScript实现滑动导航栏效果
2017/08/30 Javascript
JavaScript模块模式实例详解
2017/10/25 Javascript
微信小程序实现炫酷的弹出式菜单特效
2019/01/28 Javascript
Vue程序化的事件监听器(实例方案详解)
2020/01/07 Javascript
javascript设计模式 ? 访问者模式原理与用法实例分析
2020/04/26 Javascript
[13:38]2015国际邀请赛中国战队出征仪式
2015/05/29 DOTA
[42:32]VP vs RNG 2019国际邀请赛淘汰赛 败者组 BO3 第一场 8.21.mp4
2020/07/19 DOTA
[02:50]【扭转乾坤,只此一招】DOTA2全新版本永雾林渊开启新篇章
2020/12/24 DOTA
[01:04:09]DOTA2-DPC中国联赛 正赛 iG vs VG BO3 第二场 2月2日
2021/03/11 DOTA
Python使用urllib模块的urlopen超时问题解决方法
2014/11/08 Python
Python MySQLdb模块连接操作mysql数据库实例
2015/04/08 Python
python深度优先搜索和广度优先搜索
2018/02/07 Python
对python文件读写的缓冲行为详解
2019/02/13 Python
详解Python的数据库操作(pymysql)
2019/04/04 Python
python中not、and和or的优先级与详细用法介绍
2020/11/03 Python
python中remove函数的踩坑记录
2021/01/04 Python
如何用border-image实现文字气泡边框的示例代码
2020/01/21 HTML / CSS
英国在线汽车和面包车零件商店:Car Parts 4 Less
2018/08/15 全球购物
工商管理本科毕业生求职信范文
2013/10/05 职场文书
舞蹈毕业生的自我评价
2014/03/05 职场文书
公开承诺书格式
2014/05/21 职场文书
庆国庆国旗下讲话稿2014
2014/09/21 职场文书
先进个人自荐书
2015/03/06 职场文书
年底个人总结范文
2015/03/10 职场文书
MySQL通过binlog恢复数据
2021/05/27 MySQL
TypeScript 使用 Tuple Union 声明函数重载
2022/04/07 Javascript