什么是闭包?
闭包是能够读取其他函数内部变量的函数,就是函数内嵌套一个函数。
优点:
1.可以访问另一个函数内部的变量
2.使变量一直保存在内存中
3.防止变量污染全局
缺点:
容易造成内存泄露。通过设置xxx=null来解决;也可以通过自执行函数()()来解决,执行完就会销毁变量
垃圾回收机制:
所谓垃圾回收,核心思想就是如何判断内存是否已经不再会被使用了,如果是就视为垃圾给释放掉
1.引用计数法:跟踪记录每个值被引用的次数,当引用次数是0,则释放内存
2.标记清除法:就是从根部(在js中就是全局对象)开始出发定时扫描内存中的对象,触及到就还在使用,无法触及到的对象被标记为不再使用
应用场景:
1.setTimeout传参
//原生的setTimeout传递的第一个函数不能带参数
setTimeout(function(param){
alert(param)
},1000)
//通过闭包可以实现传参效果
function func(param){
return function(){
alert(param)
}
}
var f1 = func(1);
setTimeout(f1,1000);
2.封装变量
function Fun(){
var name = 'tom';
this.getName = function (){
return name;
}
}
var fun = new Fun();
console.log(fun.name);//输出undefined,在外部无法直接访问name
console.log(fun.getName());//可以通过特定方法去访问
3.for循环绑定click事件
for (var i = 0; i < lis.length; i++) {
// 利用for循环创建了4个立即执行函数
// 立即执行函数也成为小闭包因为立即执行函数里面的任何一个函数都可以使用它的i这个变量
(function(i) {
lis[i].onclick = function() {
console.log(i);
}
})(i);
}
4.防抖节流
// 简易版的防抖函数实现debounce:clearTimeout以及setTimeout结合
function debounce(func, wait) {
let timeout;
return function(){
let self = this;
let args = arguments;
clearTimeout(timeout);
timeout = setTimeout(function(){
func.apply(self, args);
}, wait);
}
}
// 简易版节流:使用时间戳与定时器的写法,事件立即执行但停止触发后不执行
function throttled (func, wait) {
let oldTime = new Date();
return function(...args){
let nowData = new Date();
if(nowData - oldTime >= wait){
func.apply(null, args);
oldTime = new Date();
}
}
}