JavaScript中valueOf、toString的隱式調(diào)用
今天在群上有人問這樣一個問題:
函數(shù)add可以實現(xiàn)連續(xù)的加法運(yùn)算
函數(shù)add語法如下
add(num1)(num2)(num3)...;//注意這里是省略號喲,***
使用舉例如下:
add(10)(10)=20;
add(10)(20)(50)=80;
add(10)(20)(50)(100)=180;
請用js代碼實現(xiàn)函數(shù)add。
自個琢磨了一會只能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
起初沒弄懂為什么會返回80,因為toString方法一直沒被調(diào)用啊,怎么會返回sum呢;后來知道原來toString被隱式調(diào)用了,也就有了下文。
每個對象的toString和valueOf方法都可以被改寫,每個對象執(zhí)行完畢,如果被用以操作JavaScript解析器就會自動調(diào)用對象的toString或者valueOf方法,舉栗子:
- //我們先創(chuàng)建一個對象,并修改其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)用的時候:
- 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
- //***這個未輸出任何字符串,個人猜想是這樣的:全等比較時,js解析器直接先判斷類型是否一樣,明顯一個是Object,一個是Number,所以直接不相等,根本不需要再去求值了。
由上可以看出,雖然我們沒有調(diào)用obj的任何方法,但是要使用obj進(jìn)行操作時,好像(其實就是,如果我們是創(chuàng)造js解析器的人這些就不是問題了,哎)js解析器自動幫我們調(diào)用了其toString或valueOf方法。
接下來就是探究什么時候執(zhí)行的是toString方法,什么時候執(zhí)行的是valueOf方法了。大致猜這樣:如果做加減乘除、比較運(yùn)算的時候執(zhí)行的是valueOf方法,如果是需要具體值呢就執(zhí)行的是toString方法。更嚴(yán)謹(jǐn)?shù)膶嶒瀼?fù)制一下,請原諒(原文地址):
看到這里,我們回顧一下之前我們使用 字符串和數(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'時,age變量通過調(diào)用toString函數(shù)顯式的從Number型轉(zhuǎn)換成String型。而在運(yùn)行age + ' years old'時,我們沒有顯式的調(diào)用函數(shù),age也被轉(zhuǎn)換成String型,這里就是javascript引擎做了隱式類型轉(zhuǎn)換。隱式類型轉(zhuǎn)換可以認(rèn)為 javascript引擎調(diào)用的相應(yīng)的類型轉(zhuǎn)換函數(shù)來進(jìn)行類型轉(zhuǎn)換,age + ' years old'其實等價于age.toString() + 'years old',隱式類型轉(zhuǎn)換和顯式類型轉(zhuǎn)換其實是一回事情(當(dāng)然,具體怎么優(yōu)秀的做隱式轉(zhuǎn)換的還是造js解析器的人最清楚,他怎么不告訴我們怎么造的呢... (☆▽☆)...這樣的游戲好玩么)。
哈哈,其實就是之前沒對隱式類型轉(zhuǎn)換做深入研究,只知道,哦是這樣,隱式類型轉(zhuǎn)換嘛。所以換個上面add函數(shù)的形式就不知道是怎么回事了,不過現(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