数据的转换

所有对象继承了两个转换方法:

第一个是toString(),它的作用是返回一个反映这个对象的字符串

第二个是valueOf(),它的作用是返回它相应的原始值

toString()

toString()可以看做是把一个数据转换成了相应字符串的形式,安照这个转换规则中

使用样例:

//返回相应的字符串
console.log(
({x:1,
y:1
}).toString() ); // [object Object]
console.log([1,2,3].toString()); // 1,2,3
console.log((function(x){f(x); }).toString()); //function (x){f(x); }
console.log(/\d+/g.toString()); // /\d+/g
console.log(new Date(2015,4,4).toString()); // Mon May 04 2015 00:00:00 GMT+0800 console.log(new Date(2015,4,4).valueOf()); // 1430668800000

valueOf()

每个JavaScript固有对象的 valueOf 方法定义不同。

对象 返回值
Array 数组的元素被转换为字符串,这些字符串由逗号分隔,连接在一起。其操作与 Array.toString 和 Array.join 方法相同。
Boolean Boolean 值。
Date 存储的时间是从 1970 年 1 月 1 日午夜开始计的毫秒数 UTC。
Function 函数本身。
Number 数字值。
Object 对象本身。这是默认情况。
String 字符串值。

Math 和 Error 对象没有 valueOf 方法。

------------------------------------------------------------------------------------------------------------------------------

一般来说,对象到字符串的转换经过了如下步骤:

1.如果对象具有toString()方法,则调用这个方法。如果它返回一个原始值,js将这个值转换成字符串,并返还这个字符串结果。

2.如果对象没有toString()方法,或者这个方法并不返回一个原始值,那么js将调用valueOf()方法。

3.否则,js无法从toString()或者valueOf()获得一个原始值,因此这时它将抛出一个类型错误异常。

一般来说,对象到数字的转换过程中,js做了同样类似的事情,但这里它会首先尝试使用valueOf()方法:

1.如果对象具有valueOf()方法,后者返回一个原始值,则js将这个原始值转换成数字,并返回这个数字。

2.否则,如果对象具有toString()方法,后者返回一个原始值,则js将转换并返回。

(首先js转换成相应的字符串原始值,再继续将这个原始值转换成相应的数字类型,再返回数字)

3.否则,js抛出一个类型错误异常。

对象通过toString或valueOf方法转换为原始值,JS语言核心的内置类首先尝试使用valueOf(),再尝试使用toString()

一个小李子

“1” == true;

将返回true,转换形式是:true首先转换为1,然后再执行比较。接下来字符串“1”也转换成了数字1,相等,所以返回true

另外如:

var str = new String('hello,world');
console.log(typeof str); //'object'
console.log(typeof str.valueOf()); //'string'

对于所有非日期对象来说,对象到原始值的转换基本上是对象到数字的转换

(首先调用valueOf,但日期对象则使用对象到字符串的转换模式,但这种转换只执行一次就立即被使用,不会像上面所说的那般 先转成字符串再转成相应的数字类型)

比如说,js中“+"运算符可以进行数学加法和字符串连接操作。

如果他它的其中一个操作数是对象,则js将使用特殊的方法将对象转换成原始值,而不是使用其他算术运算符的方法执行对象到数字的转换,”==“运算符类似

和”==“一样,”<"与其他运算符也会做对象到原始值的转换,但要出去日期对象的特殊情形

“-“减号运算符把两个操作数都转换成数字

比如:

var now = new Date();
console.log(now); // Date {Sat Apr 04 2015 13:21:08 GMT+0800}
console.log(typeof (now+1)); //string
console.log((now+1)); //Sat Apr 04 2015 13:21:08 GMT+08001
console.log(typeof (now-1)); //number
console.log((now-1)); //
console.log(now == now.toString()); //true
console.log(now > now -1); //true
var date = new Date();
var date_string = date.toString();
var date_value = date.valueOf();
alert(date == date_string); //true
alert(date == date_value); //false

--------------------------------------------------------------------------------------------------------------------------------

更详细了使用例子:

(摘自:http://www.jb51.net/article/32327.htm)

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方法。更进一步测试

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上阵了

JS中 toString() & valueOf()的更多相关文章

  1. js中的valueOf与toString

    所有对象继承了两个转换方法: 第一个是toString(),它的作用是返回一个反映这个对象的字符串 第二个是valueOf(),它的作用是返回它相应的原始值 一般来说,对象到字符串的转换经过了如下步骤 ...

  2. js中toString和valueOf方法的区别

    toString 方法 返回对象的字符串表示形式. 语法:objectname.toString([radix]) objectname 必需.要为其搜索字符串表示形式的对象. radix 可选.为将 ...

  3. JS中toString()、toLocaleString()、valueOf()的区别

    前言 Array.Boolean.Date.Number等对象都具有 toString().toLocaleString().valueOf()三个方法,那这三个方法有什么区别? 一.JS Array ...

  4. js 中 toString( ) 和valueOf( )

    1.toString()方法:主要用于Array.Boolean.Date.Error.Function.Number等对象转化为字符串形式.日期类的toString()方法返回一个可读的日期和字符串 ...

  5. js中.toString()和String()的一丢丢区别

    1..toString()可以将所有的的数据都转换为字符串,但是要排除null 和 undefined 例如将false转为字符串类型 <script>   var str = false ...

  6. js引用类型之valueof和tostring(三)

    一.摘要: <javascript高级程序设计第三版>一书中单独有一章对js的引用类型(Object.Array.RegExp.Function:基本包装类型:Boolean.Number ...

  7. 深入理解Javascript中的valueOf与toString

    基本上,javascript中所有数据类型都拥有valueOf和toString这两个方法,null除外.它们俩解决javascript值运算与显示的问题,本文将详细介绍,有需要的朋友可以参考下. t ...

  8. js中的tostring()方法

    http://blog.sina.com.cn/s/blog_85c1dc100101bxgg.html js中的tostring()方法 (2013-11-12 11:07:43) 转载▼ 标签: ...

  9. JS中令人发指的valueOf方法介绍

    彭老湿近期月报里提到了valueOf方法,兴致来了翻了下ECMA5里关于valueOf方法的介绍,如下: 15.2.4.4 Object.prototype.valueOf ( ) When the ...

随机推荐

  1. 源代码安装 MySQL 5.6.28

    本文内容 创建 MySQL 用户和组 解压 MySQL 源代码包 生成配置安装文件 编译和安装 MySQL 配置文件 创建 MySQL 授权表 MySQL 目录授权 启动 MySQL 验证 MySQL ...

  2. GOOGLE不能访问的解决方法

    1VPN gate 2自 由 门 3修改Windows\System32\drivers\etc hosts (复制https://github.com/txthinking/google-hosts ...

  3. String和包装类Integer\Double\Long\Float\Character 都是final类型

    String和包装类Integer\Double\Long\Float\Character\Boolean 都是final类型 不可以改变

  4. android桌面快捷方式跳转到指定activity

    AndroidManifest.xml 应用主入口配置: <activity android:name="com.*.cust.contacts.MainActivity" ...

  5. Mac 下配置 SSH 免密码安全登录

    Win下个人常使用 SecureCRT ,Mac 下感觉 SecureCRT 并不好使,常用 iTerm2+zsh 搭配使用.A连接B 无密码登陆,则A上面执行 ssh-keygen 一路回车,把 ~ ...

  6. ubuntu16.04+opencv3.1配置

    #安装必要的依赖sudo apt-get install build-essential cmakesudo apt-get install cmake Git libgtk2.0-dev pkg-c ...

  7. Oracle-ARCGIS-SDE 数据整合遇到的问题

    一. 近日在做全文检索,基础采用oracle text,版本是10g,做好管理页面后,有功能是删除索引,就是生成drop index的语句.没有想到这个全文检索的index这么直接弄还不行,经过这样删 ...

  8. Jenkins 安装或更新插件失败

    试试这个插件网址是否可以在网页中打开 http://mirror.xmission.com/jenkins/updates/current/update-center.json   如可以,把这个网址 ...

  9. Spark源码系列(二)RDD详解

    1.什么是RDD? 上一章讲了Spark提交作业的过程,这一章我们要讲RDD.简单的讲,RDD就是Spark的input,知道input是啥吧,就是输入的数据. RDD的全名是Resilient Di ...

  10. saiku 分布式实践

    saiku比较吃内存,一旦人多了,那么内存可能不够,所以会考虑主从结构,分担压力.为了保证数据的稳定性,也会有类似的考虑,那么问题来了,如何实现saiku的分布式搭建哪? 我阅读了一些国内的文章,没有 ...