实际开发中闭包的使用:
- 隐藏数据
- 如何做一个简单的cache工具
//闭包隐藏数据,只提供API
function createCache() {
const data = {} //闭包中的数据,被隐藏,不被外界访问
return {
set: function(key,value) {
data[key] = value
},
get: function(key) {
return data[key]
}
}
}
const c = createCache();
c.set('a',100);
console.log(c.get('a'));
第二题:
核心代码演示:
let i,a
for(i = 0; i < 10; i++) {
a = document.createElement('a');
a.innerHTML = i + '<br>'
a.addEventListener('click',function (e) {
e.preventDefault()
alert(i)
})
document.body.appendChild(a);
}
为什么点击每一个弹出来都是10呢?
因为我们这个代码很快就执行完了,遍历10遍,遍历每一个的时候创建a标签并绑定事件,事件还没有执行,遍历几十毫米就搞定了,那事件什么时候执行呢?什么时候点击什么时候执行。不点击永远不执行,所以说,当每个a标签被click的时候,i早就变成了10了,为什么变成10了呢?因为i的作用域是全局作用域,全局作用域的i变成10,所以alert(i),i是自由变量,就会往上找,找到全局作用域的i,当你点击a的时候,循环早就完事了,完事后i就变成10了,所以说每次点击都是10
首先要明白函数
function (e) {
e.preventDefault()
alert(i)
}
不会立马执行,当它被点击的时候才会被执行,那点击的时候,10遍循环早就做完了,所以i早就变成10了。
那怎么解决这个问题呢?
很简单
let a
for(let i = 0; i < 10; i++) {
a = document.createElement('a');
a.innerHTML = i + '<br>'
a.addEventListener('click',function (e) {
e.preventDefault()
alert(i)
})
document.body.appendChild(a);
}
效果:
let i = 0,这时候定义了一个for块级作用域,for里面的块级作用域,每次for循环执行的时候,都会形成一个新的块,i就会不一样,0-9,i都会去块级作用域寻找。针对块,每次循环产生一个块作用域;全局作用域则针对所有的块
小结:
作用域,自由变量
闭包:两种常见方式,自由变量查找规则
this