闭包
一、闭包是js中特有的现象,如何理解闭包?
-
在一个函数内部又定义了另一个函数,这个定义在内部的函数,就是闭包
-
闭包就是能够读取其他函数内部变量的函数
-
闭包是在某个作用域内定义的函数,该函数可以访问这个作用域内的所有变量
-
从作用上来说,闭包就是将函数内部和函数外部连接起来的一座桥梁
二、闭包的用途
-
在函数的外部,可以读取到函数内部的变量
-
让变量的值始终保存在内存中(不会被垃圾回收器回收)
三、闭包会导致的问题:
如果内部函数使用外部函数的变量,在外部函数执行完成之前变量会有改变时,内部只能获取最后改变的值,无法获取定义时的值,就会产生闭包
示例: <style> ul{ width: 300px; height: 300px; border: 1px solid #ccc; } </style> <script> function add(){ for (var i = 1; i <=5; i++) { var li=document.createElement('li'); li.innerText='li'+i; li.οnclick=function(){ // 当点击li时才执行该回调函数中的代码,此时循环已经结束,因此输出结果一直为6 console.log('点击了第'+i+'个li'); } document.getElementById('myul').appendChild(li); } } </script> </head> <body> <button οnclick="add()">添加元素</button> <ul id="myul"> </ul>
四、解决方法:
1.不在函数内部定义函数,将函数定义在外面,在函数内部调用
function add(){ for (var i=1;i<=5;i++) { var li=createLi(i); document.getElementById('myul').appendChild(li); } } function createLi(num){ var li=document.createElement('li'); li.innerText='li'+num; li.οnclick=function(){ console.log('点击了第'+num+'个li'); } return li; }
2.为元素添加属性,用来存储变量
function add(){ for (var i = 1; i <=5; i++) { var li=document.createElement('li'); li.innerText='li'+i; li.num=i; //存储数据 li.οnclick=function(){ console.log('点击了第'+this.num+'个li'); } document.getElementById('myul').appendChild(li); } }
3.使用let定义变量
function add(){ // 使用let声明变量,支持块级作用域,它所声明的变量所在区域不会受外部影响,称为暂时性死区 for (let i = 1; i <=5; i++) { var li=document.createElement('li'); li.innerText='li'+i; li.οnclick=function(){ console.log('点击了第'+this.num+'个li'); } document.getElementById('myul').appendChild(li); } }