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-10for(var i=1;i<=10;i++){ (function(j){ //j來接收 setTimeout(function(){ console.log(j); },j*1000); })(i)//i作為實參傳入}
如果不採用閉包的話,會有不一樣的情況。
6、getter和setterfunction 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());//aaconsole.log(next());//bbconsole.log(next());//ccconsole.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);
輸出結果:
最新評論