函數是Js中一等公民,其重要性不言而喻,現在我就把常用方法總結一下,希望大家能夠用到
函數中的緩存
? ? ? ?函數中的緩存起到很重要的作用,不僅僅提升性能,還能夠提升速度。對于一個函數來說特別重要,之前我做的一個項目,由于渲染的數據較多,當渲染數據達到200條的時候瀏覽器已經很卡頓了。我打開控制臺追溯源碼,發現發送請求兩次,new 每一個實例。第一步是把多余的請求注釋,第二步,把每一次實例分解,大致分三種數據,我就定義三個變量來存儲這三種類型數據。更改完代碼之后,直接渲染1000條數據不卡頓。瞬間覺得函數中的緩存還是相當重要 的。看一些這個代碼你就知道了
/**
* 函數緩存
* @fn {Function} 回掉函數
*
* */
var getSingle=function(fn){
? ? var result;
? ? return function(){
? ? ? ? ?return result || (result=fn.apply(this,arguments));
? ? }
}
var div=getSingle(function(){
? ? ? ? var dom_div=document.createElement("div");
? ? ? ? ?dom_div.innerHTML="我是彈出層";
? ? ? ? document.body.appendChild(dom_div);
? ? ? ? return dom_div;
});
div();//第一次調用返回新創建的div
div();//第二次調用返回緩存中的div
這個緩存方式是利用到閉包的特性,返回一個新的函數,這個函數中帶有getSingle函數中局部的變量 result引用。所有result會一直存在內存中。當我們第一次調用div()函數result值被賦值。第二次調用直接從內存中讀取result
函數鏈式調用
鏈式調用其實也很常用,如果你曾經已經把jQuery完爛,你對它的鏈式調用是否好奇。其實鏈式調用也是很簡單的。咱們看一個例子
/**
* 函數鏈式調用
* @elm 單個DOM節點
**/
var GetElm=function(elm){
? ? ? this.elm=elm || document.querySelector("body");
}
GetElm.prototype.setWidth=function(width){
? ? this.elm.style.width=width+"px";returnthis;
}
GetElm.prototype.setHeight=function(height){
? ? this.elm.style.height=height+"px";returnthis;
}
var dom=new GetElm(document.querySelector(".imag"));
dom.setHeight(400).setWidth(200);
首先定義了一個簡單的構造函數GetElm,然后在其原型擴展setWidth與setHeight方法。當我們實例一個GetElm以后。我們就可以使用setWidth與setHeight方法,大家已經發現setHeight與setWidth方法返回了this.這才是咱們實現鏈式調用的關鍵所在。
函數節流
函數節流對于我們來說太實用啦,因為我們開發頁面的時候經常會用到onresize,onscroll,onmousemove,如果這些事件中加雜大量的dom操作,瀏覽器肯定會卡頓。
//函數節流
/**
* 函數節流
* @fn {Function} 延遲執行函數
* @interval {Number} 延遲多久執行,默認值500毫秒
*
* */
var throttle=function(fn,interval){
? ? ? ?var _fn=fn || function(){},//保存需要延遲執行函數的引用
? ? ? ? timer,//定時器
? ? ? ? firstTime=true;//是否是第一次調用
return function(){
? ? ? ? ?var args=arguments,
? ? ? ? ?that=this;
? ? ? ?if(firstTime){//如果第一次執行不需要延遲
? ? ? ? ? ? _fn.apply(that,args);
? ? ? ? ? ? return firstTime=false;
? ? ? ?}
? ? ?if(timer){//如果定時器還在說明上一次執行還沒結束
? ? ? ? return false;
? ? }
? ? ? ?timer=setTimeout(function(){//延遲一段時間執行
? ? ? ? ? ? ? ?clearTimeout(timer);
? ? ? ? ? ? ? ?timer=null;
? ? ? ? ? ? ? _fn.apply(that,args);
? ? ? ? },interval || 500);
? ?}
}
window.onresize=throttle(function(){
? ? ? ?console.log("200");
},200)
有了函數throttle節流方法媽媽再也不用擔心我的瀏覽器會卡頓啦!這個節流函數也是用閉包實現的哦?。?!小伙伴們,下一篇內容咱就給你單獨講講閉包。
惰性加載函數
惰性加載函數功能猶如它的名字,它很懶,懶得以至于不想運行。哈哈,,,來看一下代碼吧!這段代碼之前你肯定經常用到,這是解決瀏覽器的兼容性而寫的。
` ` `
/**
* 惰性加載函數(一)
* 缺點:無論使用或者不使用,都要執行一次。
* @el 單個DOM節點
* @type {String} 事件名稱
* @handler {Function} 函數
*
* */
var addEvent=(function(win){
? ? ? if(win.addEventListener){
? ? ? ? ?return function(el,type,handler){
? ? ? ? ? ? ?el.addEventListener(type,handler,false);
? ? ? ? }
? ? ?}
? ?if(win.attachEvent){
? ? ? ? ?return function(el,type,handler){
? ? ? ? ? ? ?el.attachEvent("on"+type,handler);
? ?}
}
})(window)
/**
* 惰性加載函數(二)
* @el 單個DOM節點
* @type {String} 事件名稱
* @handler {Function} 函數
* 缺點:重新改寫原函數
* 優點:只有執行時才會改寫。
* */
var addEvent=function(el,type,handler){
? ? ? ? ? ?if(win.addEventListener){
? ? ? ? ? ? ? ? ? addEvent= function(el,type,handler){
? ? ? ? ? ? ? ? ? ?el.addEventListener(type,handler,false);
? ? ? ? ? ? ? ? ?}
? ? }else if(win.attachEvent){
? ? ? ? addEvent= function(el,type,handler){
? ? ? ? ?el.attachEvent("on"+type,handler);
? ?}
}
? ?addEvent(el,type,handler);
}
` ` `
惰性加載函數(一)比較勤快,所有呢!為了保證你的代碼能夠運行,你把這段代碼放在最上邊。這個函數其實也很簡單,瀏覽器加載則執行它,然后根據addEventListener與attachEvent的支持情況返回一個匿名函數給addEvent。你呢!只負責調用就行啦!它的缺點是最少執行一次。
惰性加載函數(二)跟它名字一樣,“不要跟我比懶,我懶得跟你比”。只有在你調用它的時候它會根據addEventListener與attachEvent的支持情況從寫addEvent函數。
總結
函數真的很重要,在你學習js的時候,你一定要深入去學習函數。沒有了函數可以說js跟廢物一樣。就拿上邊來看,它就幫我們解決了好多平時都經常遇到的問題。
代碼是一種神奇的東西,我們可以驅動它干好多事情。為什么我們不好好做一個控制者呢!!