首先我们需要知道什么是高级函数
- 函数作为参数传递
- 函数作为返回值输出
满足以上一个条件就可以称之为高阶级函数
函数作为参数传递
看一下例子
function iterator () {
const obj = {
message: '123'
status: false
}
obj.status = true
return obj
}
const obj2 = iterator()
console.log(obj2) // { message: '123', status: true }
复制代码
没毛病,but 问题来了,产品经理走过来和你提了一个需求,我们要在iterator 外面做一些事情,这个事情做完之后再判断obj.status是要等于true还是false。emmmmmm
好既然产品经理都这么说了。那我们就开干吧。
function iterator (cb) {
const obj = {
message: '123'
status: false
}
cb(obj)
return obj
}
const obj2 = iterator((obj) => {
console.log(obj2) // { message: '123', status: false }
if (true) {
obj.status = true
} else {
obj.status = false
}
})
console.log(obj2) // { message: '123', status: true }
复制代码
???? 完成了一个产品经理的需求。函数当值传递,这是一个高级函数
其实我们平时写的dom事件就是这样子方式,通过传入一个回调函数。
$('#btn').on('click', function() {
$('#massage').show();
});
复制代码
传入了一个函数,当click监听到了信息,就会执行你传入的函数。
让我们来个稍微高级点的。
观察者模式
class observer {
constructor() {
// 用来保存所有的事件
this.obj = {}
}
emit (str) {
// 发布一个事件
const params = Array.prototype.slice.call(arguments, 1)
this.obj[str] = (cb) => {
cb(...params)
}
}
on (str, fn) {
// 执行一个事件
this.obj[str](fn)
}
}
const ob = new observer()
ob.emit('click', 1234, 'abcd')
ob.on('click', (a,b) => {
console.log(a,b) // 1234, 'abcd'
})
复制代码
没毛病,虽然这个代码缺乏严谨,but 我们只是为了展示一下搞基函数的方式之一函数当参数传递。
函数作为返回值输出
function func () {
let a = 1
return function () {
return a++
}
}
let bb = func()
cosnole.log(bb())
cosnole.log(bb())
cosnole.log(bb())
cosnole.log(bb())
复制代码
相信大家对这个会打印啥都不陌生吧。
//1 2 3 4
复制代码
每个函数都是一个闭包,js访问一个变量是,会从自身作用域开始查找再慢慢向上查找,找到的第一个就取值。func这个函数 return 的这个function 没有a这个变量,所以就报错?no 但是它父亲有啊。它会向上找到后执行操作。最后外面js又发现全局变量bb引用了 这个function。所以js的自动垃圾回收机制放了这个a变量一马,没有回收它.
so 我们再来个稍微高级点的。
节流
function debounce(fn, time) {
// 记录当前执行函数状态
let timer = null;
let context = this;
let args = arguments;
return function() {
if (timer) {
// 任你滑,多执行一次算我输
return false
}
timer = setTimeout(function() {
clearTimeout(timer);
timer = null
fn.apply(context, args);
}, time || 500);
}
}
function foo() {
console.log('你过来啊');
}
// 过 2 秒触发一次
window.addEventListener('scroll', debounce(foo, 2000));
复制代码
这是一个简单的节流函数,作用就是节流。卧槽这么粗暴的吗? 是的,咱们是一篇讲解搞基函数的文章,说什么节流。要什么手表.
通过返回一个函数,我们实现了,一个简单的节流函数。这是有同学问,为啥那么复杂,我们直接把timer变成一个全局变量不行吗?可以的。为啥不这样做你自己去想吧。知道了答案请留言。谢谢。
我们的高级函数有很多玩法,比如柯理化和反柯理化。学无止境啊。