闭包的概念及应用场景
闭包就是指那些能够访问自由变量的函数
自由变量指函数中使用的,既不是函数从参数也不是函数局部变量的变量
- 从理论角度: 所有的函数都是闭包。
- 从实际角度:
- 即使创建他的上下午已经销毁,它仍然存在(比如:内部函数,从父函数返回)
- 代码中引用了自由变量
引用场景
- 柯里化函数 避免频繁调用具有相同参数的函数,同时又可以轻松服用
封装一个高阶函数
function getArea(width, height) {
return width * height;
}
const area1 = getArea(10, 20);
const area2 = getArea(10, 30);
const area3 = getArea(10, 40);
function getArea(width) {
return (height) => {
return width * height;
}
}
const getTenWidthArea = getArea(10);
const area2 = getTenWidthArea(30);
const area3 = getTenWidthArea(40);
-
实现私有方法/变量 其实就是模块的方式,现代化的打包最终其实就是每个模块的代码项目独立
-
匿名自执行函数
var fun = (function() {
var num = 0;
return function() {
num++;
return num;
}
})();
console.log(fun())
console.log(fun())
console.log(fun())
- 缓存一些结果 在外部函数创建一个数组,闭包函数可以更改/获取数组的值
function funParent() {
let memo = []; // 生命周期被延长了
function funTwo(i) {
memo.push(i);
console.log(memo)
}
return funTwo
}
const fn = funParent();
fn(1)
fn(2)
练习题
- 第一个
// 实现一个compose 函数,用法如下
function fn1(x) {
return x + 1
}
function fn2(x) {
return x + 2
}
function fn3(x) {
return x + 3
}
function fn4(x) {
return x + 4
}
const a = compose(fn1, fn2, fn3, fn4);
console.log(a(5)) // 1+4+3+2+1
// 实现方式
// args数组列表 对应fn1, fn2, fn3, fn4
function compose(...args) {
return (x) => {
let arr = args.reduce((sum,cur) =>{
return cur(sum)
}, x)
return arr
}
}
- 第二个
function currying(fn, ...args) {
const originLenth = fn.length;
let allArgs = [...args];
const resFn = (...newArgs) => {
// 把多次传入的参数整合起来
allArgs = [...allArgs, ...newArgs];
if (allArgs.length === originLenth) {
// 长度相等的时候直接指向传入的fn函数拿到返回值
return fn(...allArgs)
} else {
return resFn
}
}
return resFn
}
const add = (a, b, c) => a+b+c;
const a1 = currying(add, 1)
const a2 = a1(2);
console.log(a2(3))
// const add = (a, b, c, f) => a+b+c+f;
// const a6 = currying(add, 1, 2, 9, 28)
// console.log(a6())
总结
- 创建私有变量
- 延长变量生命周期