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