关于javascript中的toString()和valueOf()两种方法,其实早在开始读红宝书(JavaScript高级程序设计)的时候已经有点困惑了,怎么搞出来这两个这么类似的东西,重点是不少时候它们获得的结果都是同样的,虽然以后不了了之以为对应用没什么大影响就无论了,直到如今开始写博客的时候才回头看看这个问题。javascript
好了,开始正文了。java
toString() 和 valueOf() 是对象的两个方法,你在浏览器后台输入Object.protototype就能够看到了它们是其中的两个。git
先说一下两个东西的用途:github
toString( ):返回对象的字符串表示。数组
valueOf( ):返回对象的字符串、数值或布尔值表示。浏览器
好了,写几个例子就明白返回结果了(undefined 和 null 的值就不举例了,由于它们都没有这两个方法,因此确定会报错的):设计
//先看看toString()方法的结果 var a = 3; var b = '3'; var c = true; var d = {test:'123',example:123} var e = function(){console.log('example');} var f = ['test','example']; a.toString();// "3" b.toString();// "3" c.toString();// "true" d.toString();// "[object Object]" e.toString();// "function (){console.log('example');}" f.toString();// "test,example"
//再看看valueOf()方法的结果 var a = 3; var b = '3'; var c = true; var d = {test:'123',example:123} var e = function(){console.log('example');} var f = ['test','example']; a.valueOf();// 3 b.valueOf();// "3" c.valueOf();// true d.valueOf();// {test:'123',example:123} e.valueOf();// function(){console.log('example');} f.valueOf();// ['test','example']
很清楚了,toString( )就是将其余东西用字符串表示,比较特殊的地方就是,表示对象的时候,变成"[object Object]",表示数组的时候,就变成数组内容以逗号链接的字符串,至关于Array.join(',')。 而valueOf( )就返回它自身了。code
至于迷惑的地方,就在于它们在何时被调用,举个例子:对象
var a = '3'; console.log(+a);// 3
固然了,打印结果是数字3(不是字符串‘3’),由于一元加操做符接在字符串前面就将其转换为数字了(字符串转化为数字的一种方式,至关于Number( )方法),可是若是它应用在对象上,过程是怎样的呢,再举例子:ip
//例子一 var example = {test:'123'}; console.log(+example);// NaN //例子二 同时改写 toString 和 valueOf 方法 var example = { toString:function(){ return '23'; }, valueOf:function(){ return '32'; } }; console.log(+example);// 32 //例子三 只改写 toString 方法 var example = { toString:function(){ return '23'; } }; console.log(+example);// 23
经过例子一和例子二的比较,咱们能够知道,一元加操做符在操做对象的时候,会先调用对象的valueOf方法来转换,最后再用Number( )方法转换,而经过例子二和例子三的比较,咱们能够知道,若是只改写了toString方法,对象则会调用toString方法,证实valueOf的优先级比toString高。上面例子是单独对对象上使用一元加操做符,可是,若是是字符串加对象呢?
console.log('test'+{}); //"test[object Object]"
这个很明显,对象和字符串相加,确定转换为字符串啊,因此调用了对象的toString方法,变为[object Object]了。
好了,若是是alert呢?
//例子一 var example = {test:'123'}; alert(example);// "[object Object]" //例子二 同时改写 toString 和 valueOf 方法 var example = { toString:function(){ return '23'; }, valueOf:function(){ return '32'; } }; alert(example);// "23" //例子三 只改写 valueOf 方法 var example = { valueOf:function(){ return '32'; } }; alert(example);// "[object Object]"
虽然上面结果我用双引号了,可是你知道弹窗不会将字符串的双引号表示出来的。经过上面几个例子,咱们就知道了,alert它对待对象,就和字符串和对象相加同样,就是调用它的toString( )方法,和valueOf方法无关。
好了,总结一下,通常用操做符单独对对象进行转换的时候,若是对象存在valueOf或toString改写的话,就先调用改写的方法,valueOf更高级,若是没有被改写,则直接调用对象原型的valueOf方法。若是是弹窗的话,直接调用toString方法。至于其余状况,待续……