闭包的前世今生-02-惰性函数、偏应用函数与柯里化

248 阅读3分钟

「这是我参与2022首次更文挑战的第2天,活动详情查看:2022首次更文挑战」。

继续

我们之前聊了闭包的基础,基本形式、形成原因、优点、弊端。

那我们接着来谈一谈下一个问题:闭包的作用

我们其实下面的题目已经透露闭包的作用了,类库封装、模块化封装这些业务环境都离不开闭包的身影。

以下整理一些闭包的应用

惰性函数

惰性函数是编程中的一个重要概念,可以有效提高程序的运行效率。

惰性函数表示函数执行的分支只会在函数第一次调用的时候执行,在第一次调用中,该函数会被覆盖为另一个按照合适方式执行的半数,这样任何对原函数执行过的调用就不会再经过执行的分支了。

假设我们存在某种计算十分耗时,我们需要将结果缓存下来,代码实现如下

    var catch = {}

    function square(n) {
        if (!catch[n]) {
            catch[n] = n * n;
        }
        return catch[n]
    }

这种方案就十分不优雅,我们可以使用闭包换一种写法

    var square = (function () {
        var catch = {};
        return function (n) {
            if (!catch[n]) {
                catch[n] = n * n;
            }
            return catch[n]
        }
    })()

使用异步执行函数,将对应缓存变量放在闭包之中,最终 return 出来一个函数,使我们后面还可以继续操作。 像我们常见的设计模式:单例模式,也可以使用闭包 + 惰性函数这种方法来实现

    function Singleton() {
        this.data = "123"
    }

    Singleton.getInstance = (function() {
        var instance;

        return function() {
            if (instance) {
                return instance;
            } else {
                instance = new Singleton();
                return instance;
            }
        }
    })() 

延伸:单例的应用方式?eg:全局唯一的提示框

惰性函数的还有一个常见的使用场景是:提高浏览器兼容问题的执行效率、ajax兼容性代码进行了惰性处理。

ps: 其实惰性函数就是缓存处理。

偏应用函数与柯里化

偏应用函数

假设我们有一个ajax方法,入参有三个,method、url和headers,我们将其封装为我们常用的get方法,只需要传入两个参数,method固定,或者method,url传入,headers固定。即将原有的多个传入参数通过某种手段变少,这种编码技巧叫做偏应用函数。

代码示例如下:


const ajax = (method, url, headers) => {}

// get方法
const get = (url, headers) => ajax("get", url, headers);

const myAjax = (url) => ajax(method, url, {token});

柯里化

柯里化要求每个函数入参的个数必须为1,即:我们有一个入参为x,y的函数,需要将入参x,y变成每次只传一个参数的函数。

代码示例如下:

const add = (x, y) => x + y

const curriedAdd = x => y => x + y;

//调用时

const addOne = currieAdd(1)

柯里化和偏函数本质上都是闭包应用的一个实现。

常见业务场景

  • 分割函数转CSV

const split = (regex, str) => ("" + str).split(regex)
// const getCSV = str => split(/,\s*/);

// 偏应用函数转换
const partial = (f, ...args) => (...moreArgs) => f(...args, ...moreArgs);
const getCSV = partial(split, /,\s*/)

  • VUE3 CompositionAPI

Autfu封装的vueuse,Vue CompositionAPI封装的最基础的响应式的库

  • React Hooks

与上面实例一致。

末尾指路

这是我JS闭包系列的文章合集

闭包的前世今生-01-闭包与作用域链

闭包的前世今生-02-惰性函数、偏应用函数与柯里化

闭包的前世今生-03-闭包与即时函数

闭包的前世今生-04-闭包与类库封装、模块化(Webpack)