1. 高阶函数
高阶函数就是那种输入参数里面有一个或者多个函数,输出也是函数的函数,这个在js里面主要是利用闭包实现的,最简单的就是经常看到的在一个函数内部输出另一个函数,比如
var test = function() {
return function() {}
}
这个主要是利用闭包来保持着作用域:
var add = function() {
var num = 0;
return function(a) {
return num = num + a;
}
}
add()(1); // 1
add()(2); // 2
这里的两个add()(1)和add()(2)不会互相影响,可以理解为每次运行add函数后返回的都是不同的匿名函数,就是每次add运行后return的function其实都是不同的,所以运行结果也是不会影响的。
如果换一种写法,比如:
var add = function() {
var num = 0;
return function(a) {
return num = num + a;
}
}
var adder = add();
adder(1); // 1
adder(2); // 3
这样的话就会在之前运算结果基础上继续运算,意思就是这两个 adder 运行的时候都是调用的同一个 num
2. 高阶函数实现缓存(备忘模式)
比如有个函数:
var add = function(a) {
return a + 1;
}
每次运行add(1)
的时候都会输出2
,但是输入1
每次还是会计算一下1+1
,如果是开销很大的操作的话就比较消耗性能了,这里其实可以对这个计算进行一次缓存。
所以这里可以利用高阶函数的思想来实现一个简单的缓存,我可以在函数内部用一个对象存储输入的参数,如果下次再输入相同的参数,那就比较一下对象的属性,把值从这个对象里面取出来。
const memorize = function(fn) {
const cache = {}
return function(...args) {
const _args = JSON.stringify(args)
return cache[_args] || (cache[_args] = fn.apply(fn, args))
}
}
const add = function(a) {
return a + 1
}
const adder = memorize(add)
adder(1) // 2 cache: { '[1]': 2 }
adder(1) // 2 cache: { '[1]': 2 }
adder(2) // 3 cache: { '[1]': 2, '[2]': 3 }
用JSON.stringify
把传给 adder 函数的参数变成了字符串,并且把它当做 cache 的 key,将 add 函数运行的结果当做 value 传到了 cache 里面,这样 memorize 的匿名函数运行的时候会返回cache[_args]
,如果cache[_args]
不存在的话就返回fn.apply(fn,args),把fn.apply(fn, arguments)
赋值给cache[_args]
并返回。
注意:cache不可以是Map
,因为Map的键是使用===
比较的,[1]!==[1]
,因此即使传入相同的对象或者数组,那么还是被存为不同的键。
const memorize = function(fn) { // X 错误示范
const cache = new Map()
return function(...args) {
return cache.get(args) || cache.set(args, fn.apply(fn, args)).get(args)
}
}
const add = function(a) {
return a + 1
}
const adder = memorize(add)
adder(1) // 2 cache: { [ 1 ] => 2 }
adder(1) // 2 cache: { [ 1 ] => 2, [ 1 ] => 2 }
adder(2) // 3 cache: { [ 1 ] => 2, [ 1 ] => 2, [ 2 ] => 3 }
本文是系列文章,可以相互参考印证,共同进步~
网上的帖子大多深浅不一,甚至有些前后矛盾,在下的文章都是学习过程中的总结,如果发现错误,欢迎留言指出~
参考: <JavaScript模式>P78
PS:欢迎大家关注我的公众号【前端下午茶】,一起加油吧~
另外可以加入「前端下午茶交流群」微信群,长按识别下面二维码即可加我好友,备注加群,我拉你入群~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。