「这是我参与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闭包系列的文章合集