1.作用域的问题
当调用一个函数后这个函数中声明的变量会被回收掉,为避免这种情况发生就需要一种可以保存变量的技术,就是闭包,就是函数内部调用外部的值,每当把函数内部的值赋给外面的一个变量保存时就会产生一个新的闭包。
function add () {
let n = 1
return function add2 () {
let m = 1
return function add3 () {
console.log('m'+ (++m))
console.log(++n)
}
add3()
}
}
let obj1 = add()()
obj1() //m2 2
obj1() //m3 3
2.使用闭包来获取价格区间商品
let goods = [
{
name: '张三的衣服',
price: 100
},
{
name: '张三的裤子',
price: 200
},
{
name: '张三的鞋子',
price: 300
},
{
name: '张三的手表',
price: 400
},
{
name: '张三的车子',
price: 500
},
{
name: '张三的脑袋',
price: 0
}
]
function between (a,b) {
return function (v) {
return v.price > a && v.price < b
}
}
console.log(goods.filter(between(100, 500)))
3.利用闭包完成按钮移动动画
<button id="btn1">第一个按钮</button>
<button id="btn2">第二个按钮</button>
<script>
let btns = document.querySelectorAll('button')
btns.forEach(item => {
let flag = false //通过改变flag来判断是否开启定时器
item.addEventListener('click', function () {
if (!flag) { //如果flag为真就不会执行下面的,这样就只会保存一个left和一个定时器
flag = true
let left = 0
let timer = setInterval(function () {
item.style.left = left++ + "px"
if (left >= 800) {
clearInterval(timer)
}
}, 5)
}
})
})
</script>
4.使用闭包完成排序
let goods = [
{
name: '张三的衣服',
price: 100
},
{
name: '张三的裤子',
price: 200
},
{
name: '张三的鞋子',
price: 300
},
{
name: '张三的手表',
price: 400
},
{
name: '张三的车子',
price: 500
},
{
name: '张三的脑袋',
price: 0
}
]
function order (filed, type="asc") {
return function (a,b) { //一定要返回出去给sort使用
if (type === "asc") {
return a[filed] > b[filed] ? -1 : 1
}
return a[filed] > b[filed] ? 1 : -1
}
}
let newGoods = goods.sort(order("price"))
console.table(newGoods)
5.闭包内存泄漏
因为闭包是起保存作用的,所以难免会保存一个不需要的,这时候只需要把不需要的让它=null就行了。
6.this在闭包中的遗留问题
let obj = {
haha: '张三',
fun: function () {
return function () {
return this.haha
}
}
}
let fun2 = obj.fun()
console.log(fun2())
这时候this是window,打印的是undefined
旧的解决办法
let This = this
return function () {
return This.haha
}
新的解决办法
fun: function () {
return () => {
return this.haha
}
}
总之就是改变this指向,用call也可以,万变不离其宗
let obj = {
haha: '张三',
fun: function () {
return function () {
return this.haha
}
}
}
let fun2 = obj.fun()
console.log(fun2.call(obj))