1.返回值(最常用)
//1.返回值 最常用的 function fn(){ var name="hello"; return function(){ return name; } } var fnc = fn(); console.log(fnc())//hello
這個很好理解就是以閉包的形式將 name 返回。
2.函數賦值
var fn2; function fn(){ var name="hello"; //將函數賦值給fn2 fn2 = function(){ return name; } } fn()//要先執行進行賦值, console.log(fn2())//執行輸出fn2
在閉包里面給fn2函數設置值,閉包的形式把name屬性記憶下來,執行會輸出 hello。
3.函數參數
function fn(){ var name="hello"; return function callback(){ return name; } } var fn1 = fn()//執行函數將返回值(callback函數)賦值給fn1, function fn2(f){ //將函數作為參數傳入 console.log(f());//執行函數,并輸出 } fn2(fn1)//執行輸出fn2
用閉包返回一個函數,把此函數作為另一個函數的參數,在另一個函數里面執行這個函數,最終輸出 hello
4.IIFE(自執行函數)
(function(){ var name="hello"; var fn1= function(){ return name; } //直接在自執行函數里面調用fn2,將fn1作為參數傳入 fn2(fn1); })() function fn2(f){ //將函數作為參數傳入 console.log(f());//執行函數,并輸出 }
直接在自執行函數里面將封裝的函數fn1傳給fn2,作為參數調用同樣可以獲得結果 hello
5.循環賦值
//每秒執行1次,分別輸出1-10 for(var i=1;i<=10;i++){ (function(j){ //j來接收 setTimeout(function(){ console.log(j); },j*1000); })(i)//i作為實參傳入 }
如果不采用閉包的話,會有不一樣的情況,可以看我自己 閉包 的文章。
6.getter和setter
function fn(){ var name="hello" setName=function(n){ name = n; } getName=function(){ return name; } //將setName,getName作為對象的屬性返回 return { setName:setName, getName:getName } } var fn1 = fn();//返回對象,屬性setName和getName是兩個函數 console.log(fn1.getName());//getter fn1.setName("world");//setter修改閉包里面的name console.log(fn1.getName());//getter
第一次輸出 hello 用setter以后再輸出 world ,這樣做可以封裝成公共方法,防止不想暴露的屬性和函數暴露在外部。
7.迭代器(執行一次函數往下取一個值)
var arr =["aa","bb","cc"]; function incre(arr){ var i=0; return function(){ //這個函數每次被執行都返回數組arr中 i下標對應的元素 return arr[i++] || "數組值已經遍歷完"; } } var next = incre(arr); console.log(next());//aa console.log(next());//bb console.log(next());//cc console.log(next());//數組值已經遍歷完
8.首次區分(相同的參數,函數不會重復執行)
var fn = (function(){ var arr=[];//用來緩存的數組 return function(val){ if(arr.indexOf(val)==-1){//緩存中沒有則表示需要執行 arr.push(val);//將參數push到緩存數組中 console.log("函數被執行了",arr); //這里寫想要執行的函數 }else{ console.log("此次函數不需要執行"); } console.log("函數調用完打印一下,方便查看已緩存的數組:",arr); } })(); fn(10); fn(10); fn(1000); fn(200); fn(1000);
執行結果如下:
可以明顯的看到首次執行的會被存起來,再次執行直接取。
9.緩存
//比如求和操作,如果沒有緩存,每次調用都要重復計算,采用緩存已經執行過的去查找,查找到了就直接返回,不需要重新計算 var fn=(function(){ var cache={};//緩存對象 var calc=function(arr){//計算函數 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轉換成數組 var key=args.join(",");//將args用逗號連接成字符串 var result , tSum = cache[key]; if(tSum){//如果緩存有 console.log("從緩存中取:",cache)//打印方便查看 result = tSum; }else{ //重新計算,并存入緩存同時賦值給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);
輸出結果:
以上就是js閉包的9個使用場景的詳細內容,更多關于js 閉包使用場景的資料請關注服務器之家其它相關文章!
原文鏈接:https://www.cnblogs.com/smileZAZ/p/14189126.html