<!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>