JavaScript中valueOf、toString的隱式調(diào)用
今天在群上有人問(wèn)這樣一個(gè)問(wèn)題:
函數(shù)add可以實(shí)現(xiàn)連續(xù)的加法運(yùn)算
函數(shù)add語(yǔ)法如下
add(num1)(num2)(num3)...;//注意這里是省略號(hào)喲,***
使用舉例如下:
add(10)(10)=20;
add(10)(20)(50)=80;
add(10)(20)(50)(100)=180;
請(qǐng)用js代碼實(shí)現(xiàn)函數(shù)add。
自個(gè)琢磨了一會(huì)只能Google之,代碼如下:
- function add(num){
- var sum=num,
- tmp=function(v){
- sum+=v;
- return tmp
- };
- tmp.toString=function(){
- return sum
- };
- return tmp
- }
- alert( add(10)(20)(50) ) //80
起初沒(méi)弄懂為什么會(huì)返回80,因?yàn)閠oString方法一直沒(méi)被調(diào)用啊,怎么會(huì)返回sum呢;后來(lái)知道原來(lái)toString被隱式調(diào)用了,也就有了下文。
每個(gè)對(duì)象的toString和valueOf方法都可以被改寫,每個(gè)對(duì)象執(zhí)行完畢,如果被用以操作JavaScript解析器就會(huì)自動(dòng)調(diào)用對(duì)象的toString或者valueOf方法,舉栗子:
- //我們先創(chuàng)建一個(gè)對(duì)象,并修改其toString和valueOf方法
- var obj={
- i:10,
- valueOf:function(){
- console.log('執(zhí)行了valueOf()');
- return this.i+20
- },
- toString:function(){
- console.log('執(zhí)行了toString()');
- return this.valueOf()+20
- }
- }
- //當(dāng)我們調(diào)用的時(shí)候:
- alert( obj ) //50 執(zhí)行了toString() 執(zhí)行了valueOf()
- alert( +obj ) //30 執(zhí)行了valueOf()
- alert( obj>40 ) //false 執(zhí)行了valueOf()
- alert( obj==30 ) //true 執(zhí)行了valueOf()
- alert( obj===30 ) //false
- //***這個(gè)未輸出任何字符串,個(gè)人猜想是這樣的:全等比較時(shí),js解析器直接先判斷類型是否一樣,明顯一個(gè)是Object,一個(gè)是Number,所以直接不相等,根本不需要再去求值了。
由上可以看出,雖然我們沒(méi)有調(diào)用obj的任何方法,但是要使用obj進(jìn)行操作時(shí),好像(其實(shí)就是,如果我們是創(chuàng)造js解析器的人這些就不是問(wèn)題了,哎)js解析器自動(dòng)幫我們調(diào)用了其toString或valueOf方法。
接下來(lái)就是探究什么時(shí)候執(zhí)行的是toString方法,什么時(shí)候執(zhí)行的是valueOf方法了。大致猜這樣:如果做加減乘除、比較運(yùn)算的時(shí)候執(zhí)行的是valueOf方法,如果是需要具體值呢就執(zhí)行的是toString方法。更嚴(yán)謹(jǐn)?shù)膶?shí)驗(yàn)復(fù)制一下,請(qǐng)?jiān)彛?a target="_blank" >原文地址):
看到這里,我們回顧一下之前我們使用 字符串和數(shù)字加減 等操作的隱式轉(zhuǎn)換:
- var age = 30;
- age.toString() + 'year old'; // '30 year old'
- age + ' years old'; // '30 years old'
在運(yùn)行 age.toString() + 'year old'時(shí),age變量通過(guò)調(diào)用toString函數(shù)顯式的從Number型轉(zhuǎn)換成String型。而在運(yùn)行age + ' years old'時(shí),我們沒(méi)有顯式的調(diào)用函數(shù),age也被轉(zhuǎn)換成String型,這里就是javascript引擎做了隱式類型轉(zhuǎn)換。隱式類型轉(zhuǎn)換可以認(rèn)為 javascript引擎調(diào)用的相應(yīng)的類型轉(zhuǎn)換函數(shù)來(lái)進(jìn)行類型轉(zhuǎn)換,age + ' years old'其實(shí)等價(jià)于age.toString() + 'years old',隱式類型轉(zhuǎn)換和顯式類型轉(zhuǎn)換其實(shí)是一回事情(當(dāng)然,具體怎么優(yōu)秀的做隱式轉(zhuǎn)換的還是造js解析器的人最清楚,他怎么不告訴我們?cè)趺丛斓哪?.. (☆▽☆)...這樣的游戲好玩么)。
哈哈,其實(shí)就是之前沒(méi)對(duì)隱式類型轉(zhuǎn)換做深入研究,只知道,哦是這樣,隱式類型轉(zhuǎn)換嘛。所以換個(gè)上面add函數(shù)的形式就不知道是怎么回事了,不過(guò)現(xiàn)在算是弄清楚了(吧)。
參考:
http://www.cnblogs.com/rubylouvre/archive/2010/10/01/1839748.html
http://zjuwwq.gitbooks.io/jump_javascript/content/data_types/type_conversion.html