【复习01】闭包的使用

发布时间 2023-09-06 16:09:15作者: sanhuamao

简要介绍

  1. 内层访问了外层作用域的变量
  2. 当执行了外层函数,内层所引用的外层变量不会被销毁,可以延长变量生命周期
  3. 会造成内存泄漏,所以当不需要用时,将变量赋值为null

作用

1. 实现模块化

避免变量名冲突

const module = (function () {
    let count = 0
    function increase() {
        count++
    }
    function decrease() {
        count--
    }
    function getCount() {
        return count
    }

    return {
        increase,
        decrease,
        getCount
    };
})();

module.increase()

2. 实现柯里化

原始函数的参数被逐个应用于一系列嵌套的函数中。既会逐个接收参数,直到接收到的参数数量满足原始函数的参数数量,优势是可以对参数进行分开存储

const curry = (a: number) => {
	return (b: number) => a + b
}
const sum=curry(1)  // 把第一个参数储存了
sum(2)

柯里化

let curry = (fn: Function) => {
    return function curried(this: any, ...args: any[]) {
        // 传入的参数满足函数的参数数量时,函数才会正式调用
        if (args.length >= fn.length) {
            return fn.apply(this, args)
        } else {
            // 如果数量不足,继续去接收新的参数,并将新老参数进行合并
            return (...newArgs: any[]) => {
               // Array.prototype.slice.call(arguments)
                return curried.apply(this, args.concat(newArgs))
            }
        }
    }
}

3. hook应用

const useCount = (initCount: number = 0) => {
    let count = initCount
    function increase() {
        count++
    }
    function decrease() {
        count--
    }
    function getCount() {
        return count
    }
    return {
        increase,
        decrease,
        getCount
    }
}
const { increase, decrease, getCount } = useCount()

共享数据

// 共享数据
type AnyFn = (...args: any) => any
const createSharedStore = <Fn extends AnyFn>(hook: Fn) => {
    let store: any = null
    const func = (...args: any) => {
        if (!store) {
            store = hook(...args)
        }
        return store
    }
    return func as Fn
}
const useSharedCount = createSharedStore(useCount)

释放

type WithFreeFunc<P extends any[], R> = (...args: P) => R & {
    free: () => void
}
function createSharedState<P extends any[], R>(
    hook: (...args: P) => R
): WithFreeFunc<P, R> {
    let store: any = null
    const func = (...args: P) => {
        if (!store) {
            store = hook(...args)
        }
        return {
            ...store,
            // 添加手动释放内存方法
            free() {
                store = null
            }
        } as ReturnType<WithFreeFunc<P, R>>
    }
    return func
}