JavaScript中valueOf、toString的隱式調用


今天在群上有人問這樣一個問題:

函數add可以實現連續的加法運算
函數add語法如下
add(num1)(num2)(num3)...;//注意這里是省略號喲,無限
使用舉例如下:
add(10)(10)=20;
add(10)(20)(50)=80;
add(10)(20)(50)(100)=180;
請用js代碼實現函數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方法一直沒被調用啊,怎么會返回sum呢;后來知道原來toString被隱式調用了,也就有了下文。

 

先引用一段話

 

每個對象的toString和valueOf方法都可以被改寫,每個對象執行完畢,如果被用以操作JavaScript解析器就會自動調用對象的toString或者valueOf方法,舉栗子:

    //我們先創建一個對象,並修改其toString和valueOf方法
    var obj={ i:10, valueOf:function(){ console.log('執行了valueOf()'); return this.i+20 }, toString:function(){ console.log('執行了toString()'); return this.valueOf()+20 } } //當我們調用的時候:
 alert( obj ) //50 執行了toString() 執行了valueOf()
    alert( +obj )    //30 執行了valueOf()
    alert( obj>40 )    //false 執行了valueOf()
    alert( obj==30 )    //true 執行了valueOf()
    alert( obj===30 )    //false
    //最后這個未輸出任何字符串,個人猜想是這樣的:全等比較時,js解析器直接先判斷類型是否一樣,明顯一個是Object,一個是Number,所以直接不相等,根本不需要再去求值了。

 

 

由上可以看出,雖然我們沒有調用obj的任何方法,但是要使用obj進行操作時,好像(其實就是,如果我們是創造js解析器的人這些就不是問題了,哎)js解析器自動幫我們調用了其toString或valueOf方法。

接下來就是探究什么時候執行的是toString方法,什么時候執行的是valueOf方法了。大致猜這樣:如果做加減乘除、比較運算的時候執行的是valueOf方法,如果是需要具體值呢就執行的是toString方法。更嚴謹的實驗復制一下,請原諒(原文地址):

 看到這里,我們回顧一下之前我們使用 字符串和數字加減 等操作的隱式轉換:

    var age = 30; age.toString() + 'year old'; // '30 year old'
    age + ' years old'; // '30 years old'

在運行age.toString() + 'year old'時,age變量通過調用toString函數顯式的從Number型轉換成String型。而在運行age + ' years old'時,我們沒有顯式的調用函數,age也被轉換成String型,這里就是javascript引擎做了隱式類型轉換。隱式類型轉換可以認為javascript引擎調用的相應的類型轉換函數來進行類型轉換,age + ' years old'其實等價於age.toString() + 'years old',隱式類型轉換和顯式類型轉換其實是一回事情(當然,具體怎么優秀的做隱式轉換的還是造js解析器的人最清楚,他怎么不告訴我們怎么造的呢...(☆▽☆)...這樣的游戲好玩么)。
哈哈,其實就是之前沒對隱式類型轉換做深入研究,只知道,哦是這樣,隱式類型轉換嘛。所以換個上面add函數的形式就不知道是怎么回事了,不過現在算是弄清楚了(吧)。

 

參考:

http://www.cnblogs.com/rubylouvre/archive/2010/10/01/1839748.html

http://zjuwwq.gitbooks.io/jump_javascript/content/data_types/type_conversion.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM