高阶函数就是那种输入参数里面有一个或者多个函数,输出也是函数的函数,这个在js里面主要是利用闭包实现的,最简单的就是常常看到的在一个函数内部输出另外一个函数,好比前端
var test = function() { return function() {} }
这个主要是利用闭包来保持着做用域:segmentfault
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微信
好比有个函数:闭包
var add = function(a) { return a + 1; }
每次运行add(1)
的时候都会输出2
,可是输入1
每次仍是会计算一下1+1
,若是是开销很大的操做的话就比较消耗性能了,这里其实能够对这个计算进行一次缓存。
因此这里能够利用高阶函数的思想来实现一个简单的缓存,我能够在函数内部用一个对象存储输入的参数,若是下次再输入相同的参数,那就比较一下对象的属性,把值从这个对象里面取出来。app
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:欢迎你们关注个人公众号【前端下午茶】,一块儿加油吧~
另外能够加入「前端下午茶交流群」微信群,长按识别下面二维码便可加我好友,备注加群,我拉你入群~