返回
闭包 - 理解与应用
前端
2024-02-01 07:15:15
闭包剖析
闭包,全称词法闭包,是函数内部可以访问外部变量的特性。它是在函数被定义时所决定的,而不是在函数被调用时。
闭包的妙用
自由变量(最简单)
最为经典,也是最简单的例子,嵌套函数中访问其上级作用域的变量。
// 上级作用域
function sum(a, b) {
var c = a + b;
// 嵌套函数
function add() {
return c;
}
return add;
}
// 调起嵌套函数,即闭包
var result = sum(1, 2)();
console.log(result); // 3
函数工厂(进阶)
闭包的另一大妙用,就是函数工厂。通过闭包,我们可以根据需求动态创建函数。
// 闭包工厂,创建加法函数
function adder(base) {
return function(num) {
return base + num;
};
}
// 创建加 10 的函数
var add10 = adder(10);
// 创建加 20 的函数
var add20 = adder(20);
// 调用函数
console.log(add10(5)); // 15
console.log(add20(5)); // 25
私有变量(高阶)
闭包的另一个妙用,就是私有变量。通过闭包,我们可以在函数内部声明变量,而不被外部访问,从而实现封装。
// 闭包封装私有变量
function counter() {
var count = 0;
return function() {
return count++;
};
}
// 创建计数器
var counter1 = counter();
var counter2 = counter();
// 使用计数器
console.log(counter1()); // 0
console.log(counter1()); // 1
console.log(counter1()); // 2
console.log(counter2()); // 0
console.log(counter2()); // 1
闭包的陷阱
闭包虽然强大,但也存在一些陷阱,需要特别注意。
内存泄漏
闭包可能会导致内存泄漏,因为闭包函数内部保存了对外部变量的引用,即使外部变量已经不再使用,但闭包函数仍然可以访问到该变量,从而导致该变量无法被回收。
// 闭包导致内存泄漏
function createFunction() {
var list = [];
for (var i = 0; i < 10; i++) {
list.push(function() {
console.log(i);
});
}
return list;
}
// 创建闭包函数列表
var functions = createFunction();
// 释放对列表的引用
list = null;
// 调用闭包函数
functions[5](); // 10
// 内存泄漏,变量 i 无法被回收
闭包陷阱
闭包陷阱是指在闭包函数内部访问外部变量时,外部变量可能已经发生变化,从而导致闭包函数产生错误的结果。
// 闭包陷阱
function outer() {
var a = 1;
function inner() {
console.log(a);
}
return inner;
}
// 创建闭包函数
var innerFunc = outer();
// 修改外部变量
a = 2;
// 调用闭包函数,输出错误的结果
innerFunc(); // 1
// 预期结果应该是 2
结语
闭包是一个强大的工具,但它也存在一些陷阱,需要特别注意。掌握闭包的妙用与陷阱,可以在面试中脱颖而出,在开发中游刃有余。作为一名技术博客创作专家,我以独树一帜的观点展现事物,通过剖析和阐述,带领读者深入理解闭包,从而在编程世界里披荆斩棘,所向披靡。