闭包(Closure)是 JavaScript 中的一个重要概念。它指的是:一个函数和对其周围状态(scope)的引用捆绑在一起的实体。
简单来说,闭包让函数可以记住并访问所在的词法作用域,即使函数是在当前词法作用域之外执行的。
闭包有以下主要特点:
- 可以读取函数内部的变量
- 读取的时候,会使用其时的变量值
- 函数的作用域链包含着这个闭包创建时的作用域
例如:
function makeCounter() {
let count = 0;
return function() {
count++;
return count;
}
}
let counter = makeCounter();
console.log(counter()); // 1
console.log(counter()); // 2
这里 counter 是闭包,它包含了对包含它的 makeCounter 函数作用域的引用。所以每次调用 counter 都可以修改和访问 makeCounter 内的 count 变量。
闭包的主要应用场景有:
- 封装变量
- 函数柯里化
- 装饰器模式
- 细粒度权限控制
- 模拟私有方法
例如:
// 封装变量
function makeCounter() {
let count = 0;
return {
increase() {
count++;
},
getCount() {
return count;
}
};
}
let counter = makeCounter();
counter.increase();
counter.getCount(); // 1
// 函数柯里化
function curry(fn) {
return function(a) {
return function(b) {
return fn(a, b);
}
};
}
let addCurry = curry((a, b) => a + b);
let add10 = addCurry(10);
add10(20); // 30
// 装饰器模式
function makeColor(color) {
return function(target) {
target.color = color;
}
}
@makeColor('red')
class Button {
constructor() {
console.log(this.color);
}
}
let button = new Button(); // red
所以总结来说,闭包是 JavaScript 语言极为重要的功能,它使得 JavaScript 的函数更加强大与灵活。
理解闭包的工作机制与应用场景,可以帮助我们编写更加优雅与强大的代码。
在工作中,我们应熟练运用闭包来封装数据,实现柯里化,装饰器等功能。