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 相关文章推荐
JQuery 浮动导航栏实现代码
Aug 27 Javascript
js类式继承的具体实现方法
Dec 31 Javascript
javascript间隔定时器(延时定时器)学习 间隔调用和延时调用
Jan 13 Javascript
jQuery自定义图片缩放拖拽插件imageQ实现方法(附demo源码下载)
May 27 Javascript
js 作用域和变量详解
Feb 16 Javascript
JS实现动态修改table及合并单元格的方法示例
Feb 20 Javascript
JavaScript数组和对象的复制
Mar 21 Javascript
用Vue.extend构建消息提示组件的方法实例
Aug 08 Javascript
js模块加载方式浅析
Aug 12 Javascript
详解在HTTPS 项目中使用百度地图 API
Apr 26 Javascript
JavaScript学习教程之cookie与webstorage
Jun 23 Javascript
es6中class类静态方法,静态属性,实例属性,实例方法的理解与应用分析
Feb 15 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
解析如何修改phpmyadmin中的默认登陆超时时间
2013/06/25 PHP
支付宝接口开发集成支付环境小结
2015/03/17 PHP
PHP中preg_match函数正则匹配的字符串长度问题
2015/05/27 PHP
IE中createElement需要注意的一个问题
2010/07/13 Javascript
纯CSS打造的导航菜单(附jquery版)
2010/08/07 Javascript
菜鸟javascript基础资料整理3 正则
2010/12/06 Javascript
新浪微博字数统计 textarea字数统计实现代码
2011/08/28 Javascript
js获取对象为null的解决方法
2013/11/21 Javascript
js中定义一个变量并判断其是否为空的方法
2014/05/13 Javascript
jQuery实现下拉框选择图片功能实例
2015/08/08 Javascript
jQuery事件绑定用法详解(附bind和live的区别)
2016/01/19 Javascript
Bootstrap每天必学之标签页(Tab)插件
2020/08/09 Javascript
利用n 升级工具升级Node.js版本及在mac环境下的坑
2017/02/15 Javascript
原生javascript移动端滑动banner效果
2017/03/10 Javascript
Angular.js去除页面中显示的空行方法示例
2017/03/30 Javascript
用angular实现多选按钮的全选与反选实例代码
2017/05/23 Javascript
微信小程序时间选择插件使用详解
2018/12/28 Javascript
详解vue-video-player使用心得(兼容m3u8)
2019/08/23 Javascript
javascript实现的图片预览和上传功能示例【兼容IE 9】
2020/05/01 Javascript
解决vue-router 切换tab标签关闭时缓存问题
2020/07/22 Javascript
使用python开发vim插件及心得分享
2014/11/04 Python
Python装饰器(decorator)定义与用法详解
2018/02/09 Python
TensorFlow实现iris数据集线性回归
2018/09/07 Python
PyTorch中torch.tensor与torch.Tensor的区别详解
2020/05/18 Python
Python基于BeautifulSoup爬取京东商品信息
2020/06/01 Python
Speedo速比涛中国官方网站:全球领先泳装运动品牌
2018/04/24 全球购物
北美个性化礼品商店:Things Remembered
2018/06/12 全球购物
美国轮胎网站:Priority Tire
2018/11/28 全球购物
在C中是否有模拟继承等面向对象程序设计特性的好方法
2012/05/22 面试题
工程部主管岗位职责
2013/11/17 职场文书
乡镇办公室工作决心书
2014/03/11 职场文书
群众路线查摆问题及整改措施
2014/10/10 职场文书
首席执行官观后感
2015/06/03 职场文书
JavaScript继承的三种方法实例
2021/05/12 Javascript
python 如何用terminal输入参数
2021/05/25 Python
Spring Boot DevTools 全局配置学习指南
2022/03/31 Java/Android