js高阶函数模拟AOP

1.代码
    Function.prototype.before = function(beforefn) {
      let _self = this;//记录原函数
      return function(){
        console.log(this);//
        console.log(arguments);
        beforefn.call(this,arguments);//修正this值
        return _self.apply(this,arguments);
      } 
    }
    Function.prototype.after = function(afterfn) {
      let _self = this;//
      return function(){
        console.log(this);//window
        console.log(arguments);
        let ret = _self.apply(this,arguments);//修正this值,并且执行原函数
        afterfn.apply(this,arguments);
        console.log(ret);
        return ret;
      } 
    }
    let func = function(){
      console.log(2);
    }
    let func2 = func.before(function(){console.log(1)}).after(function(){console.log(3)});
    let obj = {f:func2};
    func2();
    obj.f();
2.输出结果
js高阶函数模拟AOP_第1张图片
执行结果
3.分析

func2 = func.before(function(){console.log(1)}).after(function(){console.log(3)});
最关键之处在于这一行代码,拆开来看
func.before(function(){console.log(1)})
func调用before方法,此时在 before方法体内this指向调用before方法的对象,也就是func然后返回了一个匿名函数,此时匿名函数体内_self指向最初的func方法。
再看.after(function(){console.log(3)})
匿名函数调用after方法,在after方法体内,this指向匿名函数,_self保存的是匿名函数,然后after方法返回的仍然是一个匿名函数。在这个匿名函数内_self指向before返回的匿名函数,ret是func的返回值。

然后将返回的匿名函数赋值给func2;

直接执行func2时,this指向全局,非严格模式下默认是window
当通过对象调用时,this指向调用函数的对象。

你可能感兴趣的:(js高阶函数模拟AOP)