js閉包的9個(gè)使用場(chǎng)景
1.返回值(最常用)
//1.返回值 最常用的 function fn(){ var name="hello"; return function(){ return name; } } var fnc = fn(); console.log(fnc())//hello
這個(gè)很好理解就是以閉包的形式將 name 返回。
2.函數(shù)賦值
var fn2; function fn(){ var name="hello"; //將函數(shù)賦值給fn2 fn2 = function(){ return name; } } fn()//要先執(zhí)行進(jìn)行賦值, console.log(fn2())//執(zhí)行輸出fn2
在閉包里面給fn2函數(shù)設(shè)置值,閉包的形式把name屬性記憶下來(lái),執(zhí)行會(huì)輸出 hello。
3.函數(shù)參數(shù)
function fn(){ var name="hello"; return function callback(){ return name; } } var fn1 = fn()//執(zhí)行函數(shù)將返回值(callback函數(shù))賦值給fn1, function fn2(f){ //將函數(shù)作為參數(shù)傳入 console.log(f());//執(zhí)行函數(shù),并輸出 } fn2(fn1)//執(zhí)行輸出fn2
用閉包返回一個(gè)函數(shù),把此函數(shù)作為另一個(gè)函數(shù)的參數(shù),在另一個(gè)函數(shù)里面執(zhí)行這個(gè)函數(shù),最終輸出 hello
4.IIFE(自執(zhí)行函數(shù))
(function(){ var name="hello"; var fn1= function(){ return name; } //直接在自執(zhí)行函數(shù)里面調(diào)用fn2,將fn1作為參數(shù)傳入 fn2(fn1); })() function fn2(f){ //將函數(shù)作為參數(shù)傳入 console.log(f());//執(zhí)行函數(shù),并輸出 }
直接在自執(zhí)行函數(shù)里面將封裝的函數(shù)fn1傳給fn2,作為參數(shù)調(diào)用同樣可以獲得結(jié)果 hello
5.循環(huán)賦值
//每秒執(zhí)行1次,分別輸出1-10 for(var i=1;i<=10;i++){ (function(j){ //j來(lái)接收 setTimeout(function(){ console.log(j); },j*1000); })(i)//i作為實(shí)參傳入 }
如果不采用閉包的話,會(huì)有不一樣的情況,可以看我自己 閉包 的文章。
6.getter和setter
function fn(){ var name='hello' setName=function(n){ name = n; } getName=function(){ return name; } //將setName,getName作為對(duì)象的屬性返回 return { setName:setName, getName:getName } } var fn1 = fn();//返回對(duì)象,屬性setName和getName是兩個(gè)函數(shù) console.log(fn1.getName());//getter fn1.setName('world');//setter修改閉包里面的name console.log(fn1.getName());//getter
第一次輸出 hello 用setter以后再輸出 world ,這樣做可以封裝成公共方法,防止不想暴露的屬性和函數(shù)暴露在外部。
7.迭代器(執(zhí)行一次函數(shù)往下取一個(gè)值)
var arr =['aa','bb','cc']; function incre(arr){ var i=0; return function(){ //這個(gè)函數(shù)每次被執(zhí)行都返回?cái)?shù)組arr中 i下標(biāo)對(duì)應(yīng)的元素 return arr[i++] || '數(shù)組值已經(jīng)遍歷完'; } } var next = incre(arr); console.log(next());//aa console.log(next());//bb console.log(next());//cc console.log(next());//數(shù)組值已經(jīng)遍歷完
8.首次區(qū)分(相同的參數(shù),函數(shù)不會(huì)重復(fù)執(zhí)行)
var fn = (function(){ var arr=[];//用來(lái)緩存的數(shù)組 return function(val){ if(arr.indexOf(val)==-1){//緩存中沒(méi)有則表示需要執(zhí)行 arr.push(val);//將參數(shù)push到緩存數(shù)組中 console.log('函數(shù)被執(zhí)行了',arr); //這里寫(xiě)想要執(zhí)行的函數(shù) }else{ console.log('此次函數(shù)不需要執(zhí)行'); } console.log('函數(shù)調(diào)用完打印一下,方便查看已緩存的數(shù)組:',arr); } })(); fn(10); fn(10); fn(1000); fn(200); fn(1000);
執(zhí)行結(jié)果如下:
可以明顯的看到首次執(zhí)行的會(huì)被存起來(lái),再次執(zhí)行直接取。
9.緩存
//比如求和操作,如果沒(méi)有緩存,每次調(diào)用都要重復(fù)計(jì)算,采用緩存已經(jīng)執(zhí)行過(guò)的去查找,查找到了就直接返回,不需要重新計(jì)算 var fn=(function(){ var cache={};//緩存對(duì)象 var calc=function(arr){//計(jì)算函數(shù) var sum=0; //求和 for(var i=0;i<arr.length;i++){ sum+=arr[i]; } return sum; } return function(){ var args = Array.prototype.slice.call(arguments,0);//arguments轉(zhuǎn)換成數(shù)組 var key=args.join(",");//將args用逗號(hào)連接成字符串 var result , tSum = cache[key]; if(tSum){//如果緩存有 console.log('從緩存中?。?,cache)//打印方便查看 result = tSum; }else{ //重新計(jì)算,并存入緩存同時(shí)賦值給result result = cache[key]=calc(args); console.log('存入緩存:',cache)//打印方便查看 } return result; } })(); fn(1,2,3,4,5); fn(1,2,3,4,5); fn(1,2,3,4,5,6); fn(1,2,3,4,5,8); fn(1,2,3,4,5,6);
輸出結(jié)果:
以上就是js閉包的9個(gè)使用場(chǎng)景的詳細(xì)內(nèi)容,更多關(guān)于js 閉包使用場(chǎng)景的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
基于chosen插件實(shí)現(xiàn)人員選擇樹(shù)搜索自動(dòng)篩選功能
這篇文章主要介紹了基于chosen插件實(shí)現(xiàn)人員選擇樹(shù)搜索自動(dòng)篩選功能的相關(guān)資料,需要的朋友可以參考下2016-09-09javascript模擬枚舉的簡(jiǎn)單實(shí)例
本篇文章主要是對(duì)javascript模擬枚舉的簡(jiǎn)單實(shí)例進(jìn)行了介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2014-03-03javascript實(shí)現(xiàn)圖片延遲加載方法匯總(三種方法)
看到一些大型網(wǎng)站,頁(yè)面如果有很多圖片的時(shí)候,當(dāng)你滾動(dòng)到相應(yīng)的行時(shí),當(dāng)前行的圖片才即時(shí)加載的,這樣子的話頁(yè)面在打開(kāi)只加可視區(qū)域的圖片,而其它隱藏的圖片則不加載,一定程序上加快了頁(yè)面加載的速度,跟著小編一起學(xué)習(xí)javascript實(shí)現(xiàn)圖片延遲加載吧2015-08-08js實(shí)現(xiàn)用戶離開(kāi)頁(yè)面前提示是否離開(kāi)此頁(yè)面的方法(包括瀏覽器按鈕事件)
這篇文章主要介紹了js實(shí)現(xiàn)用戶離開(kāi)頁(yè)面前提示是否離開(kāi)此頁(yè)面的方法,較為詳細(xì)的分析了javascript針對(duì)瀏覽器事件的操作技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-07-07el-table動(dòng)態(tài)渲染列、可編輯單元格、虛擬無(wú)縫滾動(dòng)的實(shí)現(xiàn)
vue對(duì)數(shù)據(jù)處理很常見(jiàn),本文主要介紹了對(duì)el-table組件二次封裝,包括對(duì)el-table的動(dòng)態(tài)渲染、單元格編輯;對(duì)于無(wú)縫滾動(dòng)的實(shí)現(xiàn),優(yōu)化大數(shù)據(jù)量下的頁(yè)面卡頓問(wèn)題,感興趣的可以了解一下2023-12-12js之點(diǎn)擊 超連接,提示一個(gè)層.點(diǎn)擊空白層消失
最近寫(xiě)一個(gè)功能,需要用到點(diǎn)擊空白層就讓指定的一個(gè)層消失,這里簡(jiǎn)單介紹下實(shí)現(xiàn)方法,需要的朋友可以參考下2007-05-05《JavaScript高級(jí)程序設(shè)計(jì)》閱讀筆記(三) ECMAScript中的引用類(lèi)型
ECMAScript中的引用類(lèi)型,主要包括Object類(lèi)、Boolean類(lèi)、Number類(lèi)、String類(lèi)、instanceof運(yùn)算符2012-02-02