<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv ...
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>閉包</title> </head> <body> <li>零</li> <li>一</li> <li>二</li> <li>三</li> <li>四</li> <script> //jS閉包 //概念:簡單的說就是一個函數外部變數被該函數調用,這樣這個函數就形成了一個閉包 //demo1: // function out() { // var a = 100; // } // out() // console.log(a); //輸出:a is not defined。 //out()函數執行之後函數執行空間被銷毀,因為此時a已經不存在了,無法被外部訪問 //demo2: // function out() { // var a = 100; // return function () { // a++ // console.log(a); // } // } // var b = out(); // b(); //輸出:101 // b(); //輸出:102 此時的a是局部變數,但是被其內部匿名函數調用,所以在out()執行之後,返回匿名函數被變數b接收 // //因為匿名函數調用了out函數裡面的a,所以out的記憶體空間並沒有被銷毀,b每次執行a在原有基礎上++ //demo3: // var li = document.getElementsByTagName("li") // function out() { // for (var i = 0; i < 5; i++) { // li[i].onclick = function () { // console.log(i); // } // } // } // out(); //輸出:不管點哪個,輸出都是5,li在迴圈的時候已經分別綁定匿名函數0-4, //匿名函數裡面的i就是out函數的內部變數i,在out()執行完之後已經迴圈到5了,所以不管點哪個都是5 //稍作修改 //demo4: // var li = document.getElementsByTagName("li") // function out() { // for (var i = 0; i < 5; i++) { // li[i].onclick = (function (j) { // return function () { // console.log(j); // } // })(i) // } // } // out(); //點幾輸出幾,li綁定了立即執行函數的返回值(也是個匿名函數),把i傳入匿名函數形參j,這樣 //立即執行函數執行完之後形參j不會被銷毀,而是被它的內部函數調用,所以每次點擊li就能調用相應的j,返回0,1,2,3,4 //但是let關鍵字可以很好的代替這個功能 //demo5: // var li = document.getElementsByTagName("li") // function out() { // for (let i = 0; i < 5; i++) { // li[i].onclick = function () { // console.log(i); // } // } // } // out(); //效果同上,點幾顯示幾 //總結: //閉包的作用:1.調用函數局部變數給外部使用 //缺點:1.由於一個函數局部變數被其他函數調用,所以這個局部變數就會一直存在,占用較大記憶體 // 2.有記憶體泄漏風險 //如有錯誤,歡迎指正 ***如果你知道身上肩負著多少希望,你就能面對任何事*** </script> </body> </html>