1、什么叫閉包?
一個作用域可以訪問另外一個函數內部的局部變量 ,或者說一個函數(子函數)訪問另一個函數(父函數)中的變量。 此時就會有閉包產生 ,那么這個變量所在的函數我們就稱之為閉包函數。比如下面例子:
function makeFn(){
var name = "Mirror";
function showName(){
alert(name)
}
return showName;
}
var myFn = makeFn();
myFn(); // "Mirror"
在以上的例子中,myFn是執行makeFn時創建的showName函數實例的引用,而showName實例仍可訪問其詞法作用域中的變量,既可以訪問到name。 由此,當myFn 被調用時,name仍可被訪問。
2、閉包的優點?
避免全局變量的污染,
3、閉包的缺點?
如果使用不當會造成內存泄露的問題,什么叫內存泄露?就是指用動態存儲分配函數動態開辟的空間,在使用完畢后未釋放,結果導致一直占據該內存單元。那怎么解決內存泄露問題呢?就是在使用完這個函數或是變量使用完成后及時的銷毀掉就可以了。
4、閉包的三個特征:
(1)函數嵌套函數
(2)函數內部可以引用函數外部的參數跟變量
(3)參數跟變量不會被我們JS中的垃圾回收機制回收。
5、閉包的使用場景:
(1)防抖與節流
// 節流函數封裝
function throttle(func, delay) {
let timer = null;
return function () {
if (!timer) {
timer = setTimeout(() => {
func.apply(this, arguments);
timer = null;
}, delay);
}
};
}
// 防抖函數封裝
function debounce(func, delay) {
let timer = null;
return function () {
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, arguments);
}, delay);
};
}
(2)函數柯里化:
JavaScript函數柯里化是一種將使用多個參數的函數轉換為一系列使用一個參數的函數的技術。
//柯里化前
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;
};
};
}
//箭頭函數簡寫
const addCurried2 = (a) => (b) => (c) => a + b + c;
console.log(addCurried1(1)(2)(3)); //6
console.log(addCurried2(1)(2)(3)); //6