1、什么叫閉包?
一個(gè)作用域可以訪問另外一個(gè)函數(shù)內(nèi)部的局部變量 ,或者說一個(gè)函數(shù)(子函數(shù))訪問另一個(gè)函數(shù)(父函數(shù))中的變量。 此時(shí)就會(huì)有閉包產(chǎn)生 ,那么這個(gè)變量所在的函數(shù)我們就稱之為閉包函數(shù)。比如下面例子:
function makeFn(){
var name = "Mirror";
function showName(){
alert(name)
}
return showName;
}
var myFn = makeFn();
myFn(); // "Mirror"
在以上的例子中,myFn是執(zhí)行makeFn時(shí)創(chuàng)建的showName函數(shù)實(shí)例的引用,而showName實(shí)例仍可訪問其詞法作用域中的變量,既可以訪問到name。 由此,當(dāng)myFn 被調(diào)用時(shí),name仍可被訪問。
2、閉包的優(yōu)點(diǎn)?
避免全局變量的污染,
3、閉包的缺點(diǎn)?
如果使用不當(dāng)會(huì)造成內(nèi)存泄露的問題,什么叫內(nèi)存泄露?就是指用動(dòng)態(tài)存儲(chǔ)分配函數(shù)動(dòng)態(tài)開辟的空間,在使用完畢后未釋放,結(jié)果導(dǎo)致一直占據(jù)該內(nèi)存單元。那怎么解決內(nèi)存泄露問題呢?就是在使用完這個(gè)函數(shù)或是變量使用完成后及時(shí)的銷毀掉就可以了。
4、閉包的三個(gè)特征:
(1)函數(shù)嵌套函數(shù)
(2)函數(shù)內(nèi)部可以引用函數(shù)外部的參數(shù)跟變量
(3)參數(shù)跟變量不會(huì)被我們JS中的垃圾回收機(jī)制回收。
5、閉包的使用場(chǎng)景:
(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ù)柯里化是一種將使用多個(gè)參數(shù)的函數(shù)轉(zhuǎn)換為一系列使用一個(gè)參數(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