所謂緩存,通俗點講就是把已經做過的事情結果先暫時存起來,下次再做同樣的事情,不用再重新去做,只要把之前的存的結果拿出來用即可,很明顯大大提升了效率。他的應用場景非常廣泛。如: 1、緩存ajax結果,大多數網站都會有產品推薦功能,比如按熱銷推薦,簡單低效的做法,每次點擊切換的時候,都要通過ajax去數 ...
所謂緩存,通俗點講就是把已經做過的事情結果先暫時存起來,下次再做同樣的事情,不用再重新去做,只要把之前的存的結果拿出來用即可,很明顯大大提升了效率。他的應用場景非常廣泛。如:
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(); //ghostwu 17 obj.show( 'ghostwu' ); //ghostwu 18 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個。。。任意參數的功能就非常的方便。完全不需要去函數體中修改,增加分支什麼的.