闭包的定义
闭包是指那些能够访问自由变量的函数
自由变量是指在函数中使用的,但既不是函数参数也不是函数局部变量的变量
- 从理论角度: 所有的函数都有可能是闭包。函数中去访问全局变量就相当于去访问自由变量
- 从实践角度:
- 即使创建它的上下文已经被销毁了,它仍然存在。(内部函数从父函数中返回)
- 代码中引用了自由变量
应用场景
- 柯里化函数 避免频繁调用具有相同参数的函数,同时能够轻松的复用 其实就是封装一个高阶函数
function getArea(width,height){
return width * height
}
const area1 = getArea(10,20)
const area2 = getArea(10,30)
const area3 = getArea(10,40)
const area4 = getArea(10,50)
// 以上函数调用,10是固定的宽度,那我们就可以简写成一个柯里化函数
function getArea(width){
return height=>width*height
}
const getTenWidthArea = getArea(10)
const area1 = getTenWidthArea(20)
const area2 = getTenWidthArea(30)
const area3 = getTenWidthArea(40)
const area4 = getTenWidthArea(50)
- 使用闭包实现私有的方法/变量
模块: 现代化的打包方式,最终就是每个模块都是相互独立的
function funcOne(i){
function funcTwo(){
console.log('数字'+i)
}
return funcTwo
}
const fa = functionOne(110)
const fb = functionOne(120)
const fc = functionOne(130)
- 匿名自执行函数
var funcOne = (function(){
var num = 0;
return function(){
num++
return num
}
})()
console.log(funcOne()) // 1
console.log(funcOne()) // 2
console.log(funcOne()) // 3
- 缓存一些结果 外部函数中创建一个数组,闭包函数可以获取或者修改这个数组的值,延长变量的生命周期。
function funParent(){
let memo = []
function funcTwo(){
memo.push(i)
console.log(memo.join('.'))
}
return funcTwo
}
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
}
function compose(...fnArr){
return function(num){
return fnArr.reduce((pre,cur)=>cur(pre),num)
}
}
const a = compose(fn1, fn2, fn3, fn4)
console.log(a(1))
function currying(fn,...args){
const originalArgLength = fn.length
let params = args
const resFn = (...innerArgs) =>{
params = params.concat(innerArgs)
if(params.length === originalArgLength) {
return fn(...params)
}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))
// 题目需求
let middleware = []
middleware.push((next)=>{
console.log(1)
next()
console.log(1.1)
})
middleware.push((next)=>{
console.log(2)
next()
console.log(2.1)
})
middleware.push((next)=>{
console.log(3)
next()
console.log(3.1)
})
let fn = compose(middleware)
fn()
// 要求实现的打印顺序
/*
1
2
3
3.1
2.1
1.1
*/
// 实现compose函数
function compose(middlewares){
const copyMiddlewares = [...middlewares]
let index = 0
let fn = ()=>{
if(index>=copyMiddlewares.length){
return
}
let middleware = copyMiddlewares[index]
index++
return middleware(fn)
}
return fn
}