1.代碼
Function.prototype.before = function(beforefn) {
let _self = this;//記錄原函數(shù)
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值,并且執(zhí)行原函數(shù)
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.輸出結(jié)果
執(zhí)行結(jié)果
3.分析
func2 = func.before(function(){console.log(1)}).after(function(){console.log(3)});
最關(guān)鍵之處在于這一行代碼,拆開來看
func.before(function(){console.log(1)})
func調(diào)用before方法,此時(shí)在 before方法體內(nèi)this指向調(diào)用before方法的對(duì)象,也就是func然后返回了一個(gè)匿名函數(shù),此時(shí)匿名函數(shù)體內(nèi)_self指向最初的func方法。
再看.after(function(){console.log(3)})
匿名函數(shù)調(diào)用after方法,在after方法體內(nèi),this指向匿名函數(shù),_self保存的是匿名函數(shù),然后after方法返回的仍然是一個(gè)匿名函數(shù)。在這個(gè)匿名函數(shù)內(nèi)_self指向before返回的匿名函數(shù),ret是func的返回值。
然后將返回的匿名函數(shù)賦值給func2;
直接執(zhí)行func2時(shí),this指向全局,非嚴(yán)格模式下默認(rèn)是window
當(dāng)通過對(duì)象調(diào)用時(shí),this指向調(diào)用函數(shù)的對(duì)象。