什么是高阶函数
至少满足以下一个条件的函数
- 函数作为参数进行传递
- 函数作为返回值输出
函数作为参数传递例子:
1、回调函数
作用:可以抽离出一部分容易变化的业务逻辑,把这部分业务逻辑放在函数参数中,这样一来可以分离业务代码中变化与不变的部分
1、ajax异步请求应用
例子:
var getUserInfo = function (userId, callback) {
let url = "https://geoapi.qweather.com/v2/city/lookup?key=eb04b1545b06437486b293fd1f23edd8&location=" + userId
$.ajax({
url: url, complete: function (data) {
if (callback instanceof Function) {
callback();
console.log("成功获取数据" + data)
}
}
})
}
getUserInfo("beijing", function () {
console.log("请查收北京天气数据")
})
2、Array.prototype.sort
let arrs = [1, 5, 7, 2, 8];
console.log(arrs)
arrs.sort(function (a, b) {
return a - b;
})
console.log(arrs)
arrs.sort(function (a, b) {
return b - a;
})
console.log(arrs)
函数作为返回值输出例子:
1、数据类型判断
var Type = {};
for (var i = 0, typeArrs; typeArrs = ["Array", "Object", "Number", "String"][i++];) {
(function (type) {
Type["is" + type] = function (obj) {
return Object.prototype.toString.call(obj) === '[object ' + type + ']'
}
})(typeArrs)
}
console.log(Type.isArray([12, 13]));
console.log(Type.isNumber([12, 13]));
2、单例
var getSingle = function (fn) {
debugger
var ret;
return function () {
ret || (ret = fn.apply(this, arguments))
console.log(ret);
}
}
var getScript = getSingle(function(){
return document.createElement('scripe')
})
var script1 = getScript()
var script2 = getScript()
alert(script1===script2)
高阶函数实现AOP
AOP概念:
(面向切面编程)主要作用是把跟核心逻辑无关的业务剥离出来,跟逻辑无关的功能通常包含:日志统计、安全控制、异常处理等。
好处:1、保持业务逻辑模块的纯净和高内聚合,2、可以很方便的复用日志统计等模块
实现:
Function.prototype.before = function(beforefn){
var _self = this;//保存原函数的引用
return function(){//返回包含了新函数和原函数的代理函数
beforefn.apply(this,arguments);//执行新函数,修正this
return _self.apply(this,arguments)//执行原函数
}
}
Function.prototype.after = function(afterfn){
var _self = this;
return function(){
var ret = _self.apply(this,arguments);
afterfn.apply(this,arguments);
return ret
}
}
var func = function(){
debugger
console.log(2)
}
// before函数返回一个函数,取决于调用它的函数
func = func.before(function(){
console.log(1);
}).after(function(){
console.log(3)
})
func();
高级函数的其他应用
1、柯里化
概念:根据传进来的参数决定什么时候执行,当参数满足规则在执行。
案例:计算每个月消费情况,每天开销不做计算,月底在计算整个月的消费总额。
var currying = function(fn){
var costs = [];
return function(){
if(arguments.length===0){
// 计算数组的合
fn.apply(this,costs);
}else{
[].push.apply(costs,arguments);
return arguments.callee
// console.log(costs);
}
}
}
var cost = (function(){
var money = 0
return function(){
let args = arguments
for(let i = 0;i