1、高阶函数是指至少满足下列条件之一的函数
函数可以作为参数被传递(应用场景:回调函数)
函数可以作为返回值输出(
应用场景
1、判断数据类型
function idNumber(obj){
return Object.prototypr.toString.call(obj) === '[objcet Number]'
}
)
可以批量注册isType函数
let Type = {}
for(let i = 0,type;type = ['String','Array','Number'][i++];){
// console.log(type)()
(function (type){
Type['is'+type] = function(obj){
return Object.prototype.toString.call(obj) == '[Object '+ type+']'
}
})(type)
}
2、getSingle单例模式
let getSingle = function(fn){
let ret;
return res || fn.call(this,arguments)
}
3、高阶函数实现AOP(面向切面编程)
AOP的主要作用是把一些跟核心逻辑无关的功能抽离出来,这些跟业务逻辑无关的功能通常包括日志统计、安全控制、异常处理等。把这些功能抽离出来后,再通过“动态织入”的方式参入业务逻辑模块中。
这么做的好处是可以保持业务逻辑的模块的纯净和高内聚性,其次是很方便的复用日志统计等功能模块
在js中实现AOP都是指把一个函数“动态织入”另一个函数之中,例如通过Function.prototype来做到这点(下面的demo体现了装饰者模式的思想)
Function.prototype.before = function(beforeFn){
let _this = this
return function(){
beforeFn.apply(this,arguments)
return _this.apply(this,arguments)
}
}
Function.prototype.after = function(afterFn){
let _this = this
return function(){
let ret = _this.apply(this,arguments)
afterFn.apply(this,arguments)
return ret
}
}
function test (params){
console.log('函数')
console.log(params)
}
function beforeTest(params){
params.b='b'
console.log('预期函数前')
}
test =test.before(beforeTest)
test =test.before(beforeTest)
test({a:1})
4、装饰者模式
在程序开发中,许多时候都并不希望某个类天生就非常庞大,一次性承担许多职责,就可以使用装饰者模式。装饰者模式可以动态的给某个对象添加一些额外的职责,而不会影响从这个类中派生其他对象。
为什么不用继承?1、不够灵活,超类和子类之间存在强耦合性2、功能服用的同时,有可能创造出大量的子类
装饰者应用:
①、当我们想给window绑定onload事件,都又不确定这事件是不是已经被其他人绑定过,为了避免之前的window.load函数中的行为,一般要先保存好原先的window.onload,把它放入新的window.onload里执行
window.onload = ()=>{
console.log(1)
}
let _onload = window.onload || function(){}
window.onload = ()=>{
_onload
console.log(2)
}
缺点:
Ⅰ必须得维护_onload这个函数,如果函数的装饰链过长,中间变量的数量也会变多。
Ⅱthis劫持的问题,window没有这个问题,但若换成document.getElementById则会报错,document.getElementById内部方法使用了this需要制定this指向
完善版本参照3、高阶函数实现AOP(面向切面编程)的例子
②动态改变参数,利用改变参数arguments同步改变的特性(严格模式不可取)
③同意验证表单