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的Tooltip插件 qtip使用详细说明
Sep 08 Javascript
Colortip基于jquery的信息提示框插件在IE6下面的显示问题修正方法
Dec 06 Javascript
jQuery学习笔记 更改jQuery对象
Sep 19 Javascript
JQuery为textarea添加maxlength属性并且兼容IE
Apr 25 Javascript
使用node.js 获取客户端信息代码分享
Nov 26 Javascript
动态加载jQuery的两种方法实例分析
Jul 17 Javascript
功能强大的Bootstrap效果展示(二)
Aug 03 Javascript
JS正则子匹配实例分析
Dec 22 Javascript
js中实例与对象的区别讲解
Jan 21 Javascript
原生javascript制作的拼图游戏实现方法详解
Feb 23 Javascript
jQuery实现html可联动的百分比进度条
Mar 26 jQuery
vue打包时去掉所有的console.log
Apr 10 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
PHP中for循环语句的几种变型
2006/11/26 PHP
将数组写入txt文件 var_export
2009/04/21 PHP
PHP常用开发函数解析之数组篇[未完结]
2012/07/30 PHP
php判断GIF图片是否为动画的方法
2020/09/04 PHP
PHP连接sql server 2005环境配置及问题解决
2014/08/08 PHP
详解PHP中的mb_detect_encoding函数使用方法
2015/08/18 PHP
js中escape对应的C#解码函数 UrlDecode
2012/12/16 Javascript
JavaScript和CSS通过expression实现Table居中显示
2013/06/28 Javascript
多种方法实现JS动态添加事件
2013/11/01 Javascript
将form表单中的元素转换成对象的方法适用表单提交
2014/05/02 Javascript
jquery datatable后台封装数据示例代码
2014/08/07 Javascript
浅谈NodeJS中require路径问题
2015/05/07 NodeJs
jQuery的Read()方法代替原生JS详解
2016/11/08 Javascript
thinkjs 文件上传功能实例代码
2017/11/08 Javascript
Vue的移动端多图上传插件vue-easy-uploader的示例代码
2017/11/27 Javascript
原生JS实现的碰撞检测功能示例
2018/05/18 Javascript
微信小程序定位当前城市的方法
2018/07/19 Javascript
Vue中使用canvas方法总结
2019/02/12 Javascript
深入了解JS之作用域和闭包
2020/06/16 Javascript
Vue实现点击当前行变色
2020/12/14 Vue.js
python中模块的__all__属性详解
2017/10/26 Python
Python爬虫实例_城市公交网络站点数据的爬取方法
2018/01/10 Python
Django自定义用户表+自定义admin后台中的字段实例
2019/11/18 Python
Python selenium抓取虎牙短视频代码实例
2020/03/02 Python
利用Python自动化操作AutoCAD的实现
2020/04/01 Python
python+appium+yaml移动端自动化测试框架实现详解
2020/11/24 Python
canvas实现高阶贝塞尔曲线(N阶贝塞尔曲线生成器)
2018/01/10 HTML / CSS
TripAdvisor瑞典:全球领先的旅游网站
2017/12/11 全球购物
介绍java中初始化块的使用
2012/09/11 面试题
Java程序员面试题
2016/09/27 面试题
科室工作的个人自我评价
2013/10/30 职场文书
单位人事专员介绍信
2014/01/11 职场文书
金融学专业大学生职业生涯规划
2014/03/07 职场文书
党员群众路线教育实践活动学习笔记
2014/11/05 职场文书
公司文体活动总结
2015/05/07 职场文书
会计专业自荐信范文
2019/05/22 职场文书