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 wmp操作代码小结(音乐连播功能)
Nov 08 Javascript
js 控制下拉菜单刷新的方法
Mar 03 Javascript
jquery easyui使用心得
Jul 07 Javascript
下拉框select的绑定示例
Sep 04 Javascript
js 自带的sort() 方法全面了解
Aug 16 Javascript
vue监听滚动事件实现滚动监听
Apr 11 Javascript
说说node中的可读流和可写流的区别
Jun 01 Javascript
微信小程序第三方框架对比 之 wepy / mpvue / taro
Apr 10 Javascript
vue发送websocket请求和http post请求的实例代码
Jul 11 Javascript
layer.prompt使文本框为空的情况下也能点击确定的方法
Sep 24 Javascript
详解vue3.0 的 Composition API 的一种使用方法
Oct 26 Javascript
JavaScript动态生成表格的示例
Nov 02 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对mongodb的扩展(初出茅庐)
2012/11/11 PHP
php session_start()出错原因分析及解决方法
2013/10/28 PHP
destoon切换城市后实现logo旁边显示地区名称的方法
2014/08/21 PHP
php中memcache 基本操作实例
2015/05/17 PHP
PHP多进程编程实例详解
2017/07/19 PHP
脚本吧 - 幻宇工作室用到js,超强推荐share.js
2006/12/23 Javascript
extjs fckeditor集成代码
2009/05/10 Javascript
js 第二代身份证号码的验证机制代码
2011/05/12 Javascript
JS获取页面窗口大小的代码解读
2011/12/01 Javascript
node.js开机自启动脚本文件
2014/12/24 Javascript
比较常见的javascript中定义函数的区别
2015/11/09 Javascript
Javascript实现鼠标框选操作  不是点击选取
2016/04/14 Javascript
对jQuary选择器的全面总结
2016/06/20 Javascript
AngularJS实现按钮提示与点击变色效果
2016/09/07 Javascript
JavaScript解析JSON格式数据的方法示例
2017/01/24 Javascript
如何正确理解javascript的模块化
2017/03/02 Javascript
使用cropper.js裁剪头像的实例代码
2017/09/29 Javascript
Vue动态控制input的disabled属性的方法
2018/06/26 Javascript
Angular 多级路由实现登录页面跳转(小白教程)
2019/11/19 Javascript
解决vuex刷新数据消失问题
2020/11/12 Javascript
[36:13]Mineski vs iG 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
Python函数中的函数(闭包)用法实例
2016/03/15 Python
常见python正则用法的简单实例
2016/06/21 Python
python并发编程之线程实例解析
2017/12/27 Python
深入浅析python 中的匿名函数
2018/05/21 Python
python-django中的APPEND_SLASH实现方法
2019/06/21 Python
PyQt5基本控件使用之消息弹出、用户输入、文件对话框的使用方法
2019/08/06 Python
softmax及python实现过程解析
2019/09/30 Python
pytorch 图像中的数据预处理和批标准化实例
2020/01/15 Python
python 实现围棋游戏(纯tkinter gui)
2020/11/13 Python
pycharm 关闭search everywhere的解决操作
2021/01/15 Python
.net C#面试题
2012/08/28 面试题
2014年秋季新学期寄语
2014/08/02 职场文书
规范化管理年活动总结
2014/08/29 职场文书
班主任高考寄语
2015/02/26 职场文书
PostgreSQL将数据加载到buffer cache中操作方法
2021/04/16 PostgreSQL