1亡脑、什么叫閉包?
一個作用域可以訪問另外一個函數(shù)內(nèi)部的局部變量 ,或者說一個函數(shù)(子函數(shù))訪問另一個函數(shù)(父函數(shù))中的變量谜喊。 此時就會有閉包產(chǎn)生 ,那么這個變量所在的函數(shù)我們就稱之為閉包函數(shù)。比如下面例子:
function makeFn(){
var name = "Mirror";
function showName(){
alert(name)
}
return showName;
}
var myFn = makeFn();
myFn(); // "Mirror"
在以上的例子中抖部,myFn是執(zhí)行makeFn時創(chuàng)建的showName函數(shù)實例的引用变屁,而showName實例仍可訪問其詞法作用域中的變量病瞳,既可以訪問到name揽咕。 由此,當myFn 被調(diào)用時套菜,name仍可被訪問亲善。
2、閉包的優(yōu)點逗柴?
避免全局變量的污染蛹头,
3、閉包的缺點戏溺?
如果使用不當會造成內(nèi)存泄露的問題渣蜗,什么叫內(nèi)存泄露?就是指用動態(tài)存儲分配函數(shù)動態(tài)開辟的空間旷祸,在使用完畢后未釋放耕拷,結(jié)果導(dǎo)致一直占據(jù)該內(nèi)存單元。那怎么解決內(nèi)存泄露問題呢托享?就是在使用完這個函數(shù)或是變量使用完成后及時的銷毀掉就可以了骚烧。
4、閉包的三個特征:
(1)函數(shù)嵌套函數(shù)
(2)函數(shù)內(nèi)部可以引用函數(shù)外部的參數(shù)跟變量
(3)參數(shù)跟變量不會被我們JS中的垃圾回收機制回收闰围。
5赃绊、閉包的使用場景:
(1)防抖與節(jié)流
// 節(jié)流函數(shù)封裝
function throttle(func, delay) {
let timer = null;
return function () {
if (!timer) {
timer = setTimeout(() => {
func.apply(this, arguments);
timer = null;
}, delay);
}
};
}
// 防抖函數(shù)封裝
function debounce(func, delay) {
let timer = null;
return function () {
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, arguments);
}, delay);
};
}
(2)函數(shù)柯里化:
JavaScript函數(shù)柯里化是一種將使用多個參數(shù)的函數(shù)轉(zhuǎn)換為一系列使用一個參數(shù)的函數(shù)的技術(shù)。
//柯里化前
function add(a, b, c) {
return a + b + c;
}
console.log(add(1, 2, 3)); //6
//柯里化后
function addCurried1(a) {
return function (b) {
return function (c) {
return a + b + c;
};
};
}
//箭頭函數(shù)簡寫
const addCurried2 = (a) => (b) => (c) => a + b + c;
console.log(addCurried1(1)(2)(3)); //6
console.log(addCurried2(1)(2)(3)); //6