標籤:i++ 代碼 eth 應用 分支 強型別 value bre 接下來
所謂緩衝,通俗點講就是把已經做過的事情結果先暫時存起來,下次再做同樣的事情,不用再重新去做,只要把之前的存的結果拿出來用即可,很明顯大大提升了效率。他的應用情境非常廣泛。如:
1、緩衝ajax結果,大多數網站都會有產品推薦功能,比如按熱銷推薦,簡單低效的做法,每次點擊切換的時候,都要通過ajax去資料庫中取出結果,其實他的結果並不是要即時去擷取,完全可以用緩衝技術儲存起來,減少資料庫處理壓力
2、單例模式,也是緩衝的應用
一、緩衝原理與應用
我們先來一個的簡單例子,比如,判斷一個數是不是素數,普通的做法:
1 function isPrime( n ){ 2 if( n ==1 ) { 3 return false; 4 }else { 5 var flag = true; 6 for( var i = 2; i < n; i++ ){ 7 if( n % i == 0 ) { 8 flag = false; 9 break;10 }11 }12 return flag;13 }14 }15 alert( isPrime( 1 ) );16 alert( isPrime( 1 ) );
每次調用isPrime都需要去把這個函數完整的執行一遍,如果判斷的素數比較大,那麼程式每次都要做大量的迴圈判斷計算,耗時很大。第一次為了擷取到結果,肯定是要完整的執行一遍程式,而第二次做重複的事情,就沒有必要再去完整的執行一次,我們完全可以把第一次的結果緩衝起來,第二次再次判斷1是不是素數,直接返回結果即可.
利用緩衝技術,改進之後的素數判斷:
1 function isPrime(value){ 2 if ( !isPrime.answers ) isPrime.answers = {}; 3 if( isPrime.answers[value] != null ){ 4 return isPrime.answers[value]; 5 } 6 var flag = value != 1; 7 for( var i = 2; i < value; i++ ){ 8 if ( value % i == 0 ) { 9 flag = false;10 break;11 } 12 }13 return isPrime.answers[value] = flag;14 }15 alert( isPrime( 2 ) );16 alert( isPrime.answers[2] );
我們為函數動態添加一個屬性answers,在第13行,儲存每個被計算過的素數結果,下次再判斷同樣的素數,在第3行判斷是否存著結果,然後返回即可,不用再重新做迴圈判斷.
還有,javascript要做點東西,dom操作是很頻繁的,如果擷取同樣的dom元素,完全可以採用緩衝技術把他們存起來
html代碼:
1 <input type="button" value="按鈕1"> 2 <input type="button" value="按鈕2"> 3 <input type="button" value="按鈕3"> 4 <input type="button" value="按鈕4"> 5 <input type="button" value="按鈕5">
1 function getElements( name ) {2 if ( !getElements.cache ) getElements.cache = {};3 return getElements.cache[name] = 4 getElements.cache[name]5 || document.getElementsByTagName( name );6 }7 8 console.log( getElements( "input" ) );9 console.log( getElements.cache["input"].length );
第二次調用getElements( ‘input‘ ) 直接就會從getElements.cache[‘input‘]把元素返回,不用再去頁面尋找dom元素。
二、函數重載原理與應用
所謂函數重載,通俗點理解,可以認為一個函數名,可以出現多種參數,實現不同的功能,比如,加法運算,1個數的時候,直接顯示,2個數的時候,求2個數的和,
3個數的時候,求3個數的和。還有,在強型別(編譯階段確定類型)語言中,重載的參數是區分類型的.
在javascript中,預設是沒有函數重載的,同名函數會產生覆蓋,最後一個會把前面的函數覆蓋.
通常,我們可以通過arguments來做文章:
1 var obj = { 2 show : function(){ 3 switch( arguments.length ){ 4 case 0: 5 alert( ‘ghostwu‘ ); 6 break; 7 case 1: 8 alert( arguments[0] ); 9 break;10 case 2:11 alert( arguments[0] + arguments[1] );12 break;13 }14 }15 }16 obj.show(); //ghostwu17 obj.show( ‘ghostwu‘ ); //ghostwu18 obj.show( 10, 20 ); //30
這樣就實現了一個簡單的重載,show方法,在不同的參數個數下,實現的功能不一樣,但是這種重載方式,擴充性很差,如果有四個參數,5個參數,6個參數。。。。等等,那麼就要添加分支了,接下來,我們就來看一個狂炫酷拽叼咋天的實現,不需要修改源碼,可以任意增加函數重載功能.
1 function addMethod( obj, name, fn ) { 2 var old = obj[name]; 3 obj[name] = function(){ 4 if ( fn.length == arguments.length ){ 5 return fn.apply( this, arguments ); 6 }else if ( typeof old == ‘function‘ ){ 7 return old.apply( this, arguments ); 8 } 9 }10 }11 12 var person = { userName : ‘ghostwu‘ };13 addMethod( person, ‘show‘, function(){14 alert( this.userName + ‘---->‘ + ‘show1‘ );15 } );16 addMethod( person, ‘show‘, function( str ){17 alert( this.userName + ‘---->‘ + str );18 } );19 addMethod( person, ‘show‘, function( a, b ){20 alert( this.userName + ‘---->‘ + ( a + b ) );21 } );22 person.show();23 person.show( 10 );24 person.show( 10, 20 );
這樣擴充的函數,如果再想添加4個,5個。。。任意參數的功能就非常的方便。完全不需要去函數體中修改,增加分支什麼的.
[js高手之路]效能最佳化技巧 - 緩衝與函數重載實戰