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面向对象编程(二) 构造函数的继承
Aug 28 Javascript
JavaScript执行顺序详细介绍
Dec 04 Javascript
js中window.open()的所有参数详细解析
Jan 09 Javascript
jQuery时间插件jquery.clock.js用法实例(5个示例)
Jan 14 Javascript
JavaScript实现给定时间相加天数的方法
Jan 25 Javascript
JS组件Form表单验证神器BootstrapValidator
Jan 26 Javascript
JS html时钟制作代码分享
Mar 03 Javascript
Node.js调用fs.renameSync报错(Error: EXDEV, cross-device link not permitted)
Dec 27 Javascript
jQuery 防止相同的事件快速重复触发方法
Feb 08 jQuery
vue组件传递对象中实现单向绑定的示例
Feb 28 Javascript
Vue项目引进ElementUI组件的方法
Nov 11 Javascript
对vuex中store和$store的区别说明
Jul 24 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
77A一级收信机修理记
2021/03/02 无线电
php桌面中心(一) 创建数据库
2007/03/11 PHP
PHP微信刮刮卡 附微信接口
2016/07/22 PHP
jquery做的一个简单的屏幕锁定提示框
2014/03/26 Javascript
使用jquery解析XML示例代码
2014/09/05 Javascript
JavaScript onkeydown事件入门实例(键盘某个按键被按下)
2014/10/17 Javascript
JS实现5秒钟自动封锁div层的方法
2015/02/20 Javascript
详解AngularJS的通信机制
2015/06/18 Javascript
js实现全国省份城市级联下拉菜单效果代码
2015/09/07 Javascript
javascript执行环境及作用域详解
2016/05/05 Javascript
基于JavaScript实现回到页面顶部动画代码
2016/05/24 Javascript
jQuery时间验证和转换为标准格式的时间格式
2017/03/06 Javascript
Angularjs的键盘事件的绑定
2017/07/27 Javascript
two.js之实现动画效果示例
2017/11/06 Javascript
仿vue-cli搭建属于自己的脚手架的方法步骤
2019/04/17 Javascript
js常见遍历操作小结
2019/06/06 Javascript
JavaScript监听触摸事件代码实例
2019/12/30 Javascript
Python处理字符串之isspace()方法的使用
2015/05/19 Python
使用TensorFlow实现二分类的方法示例
2019/02/05 Python
Python3.4学习笔记之类型判断,异常处理,终止程序操作小结
2019/03/01 Python
详解python--模拟轮盘抽奖游戏
2019/04/12 Python
python3+PyQt5 实现Rich文本的行编辑方法
2019/06/17 Python
Python numpy.zero() 初始化矩阵实例
2019/11/27 Python
Python中Flask-RESTful编写API接口(小白入门)
2019/12/11 Python
Python 调用有道翻译接口实现翻译
2020/03/02 Python
django的模型类管理器——数据库操作的封装详解
2020/04/01 Python
HTML5 Canvas实现放大镜效果示例
2020/03/25 HTML / CSS
应届生新闻编辑求职信
2013/11/19 职场文书
机修工岗位职责
2013/11/24 职场文书
老公给老婆的道歉信
2014/01/10 职场文书
销售经理岗位职责
2015/01/31 职场文书
手机销售员岗位职责
2015/04/11 职场文书
大学新生入学感想
2015/08/07 职场文书
JavaScript继承的三种方法实例
2021/05/12 Javascript
如何使用Python实现一个简易的ORM模型
2021/05/12 Python
SQL 尚未定义空闲 CPU 条件 - OnIdle 作业计划将不起任何作用
2021/06/30 SQL Server