JavaScript中對象與函數的某些事[JavaScript語言精粹-N1]

來源:互聯網
上載者:User

今天在讀《JavaScript語言精粹》的時候,關於函數的一個部分,始終覺得有點難以理解,代碼如下:    1: var obj = (function(){   2:     var value = 0;   3:        4:     return {   5:         increment:function(inc){   6:             value += typeof inc == "number"?inc:1;   7:         },   8:         getValue:function(){   9:             return value;  10:         }  11:     };  12: }());注意代碼最後的標黃色的一對括弧,書中是這樣描述的“我們並沒有把一個函數賦值給obj,我們是把調用該函數後返回的結果賦值給它,該函數返回一個包含兩個方面的對象,並且這些方法繼續享有訪問value變數的特權”。其實像這樣代碼,用的也比較多,只是從來沒有仔細琢磨過,如果去掉了最後的一對括弧,那麼,返回的就是一個函數(對象)了。 如果我們在代碼中這樣調用上面的obj,則可以直接使用,執行typeof obj 返回結果為”object”,如:    1: obj.increment(1);   2: alert(obj.getValue());//1   3: obj.increment(2);   4: alert(obj.getValue());//3如果去掉最後的一對括弧,執行typeof obj 返回結果為“function”,需要使用先聲明初始化的方式,才能使用這個對象,如:    1: var o = obj();   2: o.increment(1);   3: alert(o.getValue());//1   4: o.increment(2);   5: alert(o.getValue());//3這樣似乎理解了有沒有那對括弧的區別。但是作者後面舉的Fibonacci例子,才讓我恍然大悟,原來它還有這麼個好的用處。即,函數可以將先前的操作結果記錄在某個對象裡,從而避免無謂的重複運算。 我們通過普通的遞迴方式,計算Fibonacci數值,代碼如下:    1: var totalTimes = 0;   2:     3: var fibonacci = function (n){   4:     totalTimes +=1;   5:     return n<2?n:fibonacci(n-1) + fibonacci(n-2);   6: }   7:     8: function calculateFibonacci(){   9:     totalTimes = 0;  10:     for(var i =0;i<11;i++){  11:         document.getElementById("rlt").innerHTML +="//"+i+":"+fibonacci(i)+"<br/>";  12:     }  13:     document.getElementById("rlt").innerHTML+="//totalTimes:"+totalTimes+"<br/>";  14: }連續執行兩次,我們會看到如下的結果:    1: //0:0   2: //1:1   3: //2:1   4: //3:2   5: //4:3   6: //5:5   7: //6:8   8: //7:13   9: //8:21  10: //9:34  11: //10:55  12: //totalTimes:453  13: //0:0  14: //1:1  15: //2:1  16: //3:2  17: //4:3  18: //5:5  19: //6:8  20: //7:13  21: //8:21  22: //9:34  23: //10:55  24: //totalTimes:453是的,兩次都是執行了453次。因為每次都要重新從0,1開始計算。 但是,如果我們使用了如下代碼(注意它最後的一對括弧):    1: var totalTimes = 0;   2: var fibonacciMemo = function(){   3:     var meno = [0,1];   4:     var fib = function(n){   5:         totalTimes +=1;   6:         var result = meno[n];   7:         if(typeof result != "number"){   8:             result = fib(n-1) + fib(n-2);   9:             meno[n] = result;  10:         }  11:         return result;  12:           13:     };  14:     return fib;  15: }();  16:    17: function calculateFibonacciEx()  18: {  19:     totalTimes = 0;  20:     for(var i =0;i<11;i++){  21:         document.getElementById("rlt").innerHTML +="//"+i+":"+fibonacciMemo(i)+"<br/>";  22:     }  23:     document.getElementById("rlt").innerHTML+="//totalTimes:"+totalTimes+"<br/>";  24: }連續執行兩次,我們看到的結果卻是這樣:    1: //0:0   2: //1:1   3: //2:1   4: //3:2   5: //4:3   6: //5:5   7: //6:8   8: //7:13   9: //8:21  10: //9:34  11: //10:55  12: //totalTimes:29  13: //0:0  14: //1:1  15: //2:1  16: //3:2  17: //4:3  18: //5:5  19: //6:8  20: //7:13  21: //8:21  22: //9:34  23: //10:55  24: //totalTimes:11是的,第一次執行了29次計算,第二次只執行了11次計算。原因在於我們把結果儲存在了meno這個數組中。 當然,我們也可以通過其它方式,如全域變數的形式,將結果儲存下來,但是全域變數正是作者極力反對的應用和儲存模式之一,而且這個計算結果的儲存,本來就是對外透明的,調用它的人需要的只是計算結果,並不需要知道其中如何儲存,或者說我們並不需要這個計算函數以外的其它任何(全域)變數,或者任何後來維護這段代碼的人,不需要被告知在其它不知道的地方,有計算的中間結果需要他來做多餘的維護工作! 當然,我們也可以不用去省掉那400多次計算,不用關心程式的效率,或者不用擔心使用者的瀏覽器有多慢! 其實到現在也沒有相通,它們之間用處的區別或是優缺點在哪兒,因為始終沒想明白說這件事的Point在哪兒,所以,博文的標題總覺得沒說清楚哈!希望大家給予指點!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.