什么是闭包
闭包是指有权访问另一个函数作用域中的变量的函数.
也就是说:
- 可以在函数外部访问函数内部的局部变量.
- 让这些变量始终保存在内存中, 不会随着函数的结束而自动销毁.
闭包例子
- 使用闭包获取区间商品
上面的代码中有两个函数, 一个是between, 一个是between里返回的匿名函数.根据闭包的定义, 匿名函数内可以访问between函数中的形参a和b.let fruits = [{'name': 'apple','price': 6},{'name': 'banana','price': 10},{'name': 'orange', 'price': 20}]; function between(a, b) { return function(v) { return v.price >= a && v.price <= b; } } //获取5~15价格之间的水果信息 console.table(fruits.filter(between(5,15)));
- 使用闭包做计时器
llet clockBtn = document.querySelectorAll('button'); let hasInterval = false; function timmer() { return function() { if(!hasInterval) { let n = 1; hasInterval = true; setInterval(function(){ console.log(n++); }, 1000) } } } clockBtn[0].addEventListener('click', timmer())
- 使用闭包根据字段排序
let fruits = [{'name': 'apple','price': 6,'weight': 12},{'name': 'banana','price': 10, 'weight': 16},{'name': 'orange', 'price': 20, 'weight': 14}]; function order(field) { return function(a,b) { return a[field] > b[field] ? 1 : -1; } } console.table(fruits.sort(order('price'))); console.table(fruits.sort(order('weight')));
- 闭包的内存泄漏解决方法
let divs = document.querySelectorAll('div'); divs.forEach(function(item){ let desc = item.getAttribute('desc'); item.addEventListener('click', function(){ console.log(desc); console.log(item); }) item = null; })
- this 在闭包中的历史遗留问题
解决1 this重新赋值:let oj = { user: 'Allen', getUser: function() { return function() { console.log(this.user); // undefind } } } let a = oj.getUser(); a();
解决2 使用箭头函数:let oj = { user: 'Allen', getUser: function() { let _this = this; return function() { console.log(_this.user); // Allen } } } let a = oj.getUser(); a();
let oj = { user: 'Allen', getUser: function() { return ()=>{ console.log(this.user); //Allen } } } let a = oj.getUser(); a();