1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8" /> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 6 <title>Document</title> 7 </head> 8 <body> 9 <script> 10 // 1.閉包無處不再,需要你去識別它。基於作用域書寫代碼時產生的自然結果,我們不需要為了利用它而刻意的去創建一個閉包 11 // 2.閉包是一種方式,他是一個能夠引用其內部作用域變量的表達式 12 // 3.以下這個案例就是一個閉包,因為匿名函數(say)是在另外一個函數中聲明的,在js中如果另一個函數使用了funtion關鍵字,則創建了閉包 13 // 4.在js中 如果在一個函數A中聲明了另外一個函數B(出現了閉包),那么你調用了A函數以后,A里邊的局部變量依然是可以被訪問的 14 /* function sayHello(name) { 15 var text = name; // 局部變量text 16 var say = function () { 17 console.log(text); 18 }; 19 return say; 20 } 21 22 var say2 = sayHello("lily"); 23 24 say2(); //lily */ 25 26 // 27 /* function say667() { 28 // 局部變量num最后會保存在閉包中 29 var num = 42; 30 var say = function () { 31 console.log(num); 32 }; 33 num++; 34 return say; 35 } 36 var sayNumber = say667(); 37 //通常一個函數執行完成以后,整個內部的作用域都會被銷毀,因為引擎有垃圾回收機制來釋放不在使用的空間 38 //而閉包的神奇之處就是 可以阻止這個事情的發生,內部作用域依然存在,因為sayNumber還在使用這個作用域 39 sayNumber(); // 輸出 43 */ 40 41 // 42 /* var a, b, c; 43 function fn1() { 44 // 局部變量num最后會保存在閉包中 45 var num = 42; 46 // 將一些對於函數的引用存儲為全局變量 47 a = function () { 48 console.log(num); 49 }; 50 b = function () { 51 num++; 52 }; 53 c = function (x) { 54 num = x; 55 }; 56 } 57 fn1(); 58 b(); 59 a(); // 43 60 c(5); 61 a(); // 5 62 var oldLog = a; 63 //在上邊的案例中,當我們再次調用fn1時候,一個新的閉包就被創建了,舊閉包的變量 a b c被新閉包的函數覆蓋 64 // 每次調用fn1 都會創建一個新的閉包 65 fn1(); 66 a(); // 42 67 oldLog(); // 5 */ 68 69 // 70 function buildList(list) { 71 var result = []; 72 for (var i = 0; i < list.length; i++) { //for循環已經執行完了,此時i為3, 73 var item = "item" + i; 74 result.push(function () { 75 console.log(item + " " + list[i]); 76 }); 77 } 78 return result; 79 } 80 function testList() { 81 var fnlist = buildList([1, 2, 3]); 82 83 for (var j = 0; j < fnlist.length; j++) { 84 fnlist[j](); //打印3次 ‘item2 undefined’ 85 } 86 } 87 testList(); 88 </script> 89 </body> 90 </html>