亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

Javascript aop(面向切面編程)之around(環繞)分析

2019-11-20 12:34:33
字體:
來源:轉載
供稿:網友

Aop又叫面向切面編程,其中“通知”是切面的具體實現,分為before(前置通知)、after(后置通知)、around(環繞通知),用過spring的同學肯定對它非常熟悉,而在js中,AOP是一個被嚴重忽視的技術點。但是利用aop可以有效的改善js代碼邏輯,比如前端框架dojo和yui3中AOP則被提升至自定義事件的一種內在機制,在源碼中隨處可見。得益于這種抽象使得dojo的自定義事件異常強大和靈活。dojo中aop的實現在dojo/aspect模塊中,主要有三個方法:before、after、around,本文會帶領大家一步步實現around方法,后續文章將會深入解析dojo/aspect模塊的結構體系。

js要實現環繞通知,最簡單也最應被想到的就是利用callback(回調)

advice = function(originalFunc){ console.log("before function"); originalFunc(); console.log("after function");}var obj = { foo: function(){ console.log('foo'); }}advice(obj.foo)

結果:

before function
foo
after function  
哈哈,太簡單了,是不是可以回去睡覺了。。。。  

可是,是不是有點太粗糙了。。。。說好的環繞呢。。。。至少下次調用obj.foo也應該是這個結果,而不是一個干巴巴的“foo”;為此我我們需要在改動一下,利用一下閉包

advice = function(originalFunc){ return function() { console.log("before function"); originalFunc(); console.log("after function"); }}var obj = { foo: function(){ console.log(this.name); }, name: "obj"}obj.foo = advice(obj.foo)obj.foo()

 輸出:

before function

after function

看起來達到了環繞的效果,but說好的name哪去了。。。。

在advice返回的閉包中我們還要處理作用域問題

advice = function(originalFunc){ return function() { console.log("before function"); originalFunc(); console.log("after function"); }}var obj = { foo: function(){ console.log(this.name); }, name: "obj"}keepContext = function() { return obj['foo'].call(obj);}obj.foo = advice(keepContext);

看起來是利用call解決了作用域問題,我們運行一下看看:

臥槽,難道這就是傳說中的死循環。。。。

  看來還是得改變一下,借助一個中間變量消除死循環

advice = function(originalFunc){ return function() { console.log("before function"); originalFunc(); console.log("after function"); }}var obj = { foo: function(){ console.log(this.name); }, name: "obj"}var exist = obj.foo;keepContext = function() { return exist.call(obj);}obj.foo = advice(keepContext);obj.foo();

輸出:

before function
obj
after function  

哈哈,世界突然變得美好了。。。。
但是這一堆代碼看起來是不是太low了,我們是不是要來點高大上的抽象,嗯,我也是這么想的

function around(obj, prop, advice){ var exist = obj[prop]; var advised = advice(function(){ return exist.call(obj, arguments); }); obj[prop] = advised;}advice = function(originalFunc){ return function() { console.log("before function"); originalFunc(); console.log("after function"); }}var obj = { foo: function(){ console.log(this.name); }, name: "obj"}around(obj, 'foo', advice);obj.foo();

around方法將處理過程與具體對象解耦;advice只要按照如下格式來書寫,就可以達到around的效果

advice = function(originalFunc){ return function() { //before originalFunc(); //after }}

哈哈,瞬間高大上,狂拽酷炫掉渣天,有木有。。。。

  

  那么問題來了:如果不小心多調用了一次around方法腫么辦。。。。 額。。。。這是個問題 我們是不是應該讓around返回一個句柄,里面有個remove方法,消除綁定,就像綁定/移除事件一樣。

  所為remove,就是讓函數下次執行時不在執行對應的around方法,而僅僅運行originalFunc方法

function around(obj, prop, advice){ var exist = obj[prop]; var previous = function(){ return exist.call(obj, arguments); }; var advised = advice(previous); obj[prop] = advised;  return { remove: function(){ obj[prop] = exist; advice = null; previous = null; exist = null; obj = null; } }}var count = 1;advice = function(originalFunc){ var current = count++; return function() { console.log("before function " + current); originalFunc(arguments); console.log("after function " + current); }}var obj = { foo: function(arg){ console.log(this.name + " and " + arg); }, name: "obj"}h1 = around(obj, 'foo', advice);h2 = around(obj, 'foo', advice);obj.foo();h1.remove();obj.foo();h2.remove();obj.foo();

輸出:

before function 2before function 1obj and [object Arguments]after function 1after function 2obj and undefinedbefore function 1

這個。。不但結果有點亂。。。還報錯了。。。。是可忍,叔不可忍,叔可忍,嫂不可忍!

  啊,閉包。。。請賜予我力量吧!

function around(obj, prop, advice){ var exist = obj[prop]; var previous = function(){ return exist.apply(obj, arguments); }; var advised = advice(previous); obj[prop] = function(){ //當調用remove后,advised為空 //利用閉包的作用域鏈中可以訪問到advised跟previous變量,根據advised是否為空可以來決定調用誰 return advised ? advised.apply(obj, arguments) : previous.apply(obj, arguments); };  return { remove: function(){ //利用閉包的作用域鏈,在remove時將advised置空,這樣執行過程中不會進入本次around //這幾個不能刪 //obj[prop] = exist; advised = null; advice = null; //previous = null; //exist = null; //obj = null; } }}var count = 1;advice = function(originalFunc){ var current = count++; return function() { console.log("before function " + current); originalFunc.apply(this, arguments); console.log("after function " + current); }}var obj = { foo: function(arg){ console.log(this.name + " and " + arg); }, name: "obj"}h1 = around(obj, 'foo', advice);h2 = around(obj, 'foo', advice);obj.foo('hello world');h1.remove();obj.foo('hello world');h2.remove();obj.foo('hello world');

輸出:

before function 2before function 1obj and hello worldafter function 1after function 2before function 2obj and hello worldafter function 2obj and hello world

打完,收功!

  第一次通宵寫博客也是醉了,兩點鐘聽到隔壁fuck me,四點鐘聽到烏鴉啼鳴,還有一種不知道什么鳥,啾啾的叫,五點鐘這個時候一堆鳥叫。。。。

參考文章:

使用AOP改善javascript代碼

yui3的AOP(面向切面編程)和OOP(面向對象編程)

面向切面編程(AOP)的理解

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
最近2019免费中文字幕视频三| 久久久www成人免费精品张筱雨| 日韩成人中文字幕| 日韩精品在线视频美女| 欧美做受高潮电影o| 亚洲一二三在线| 4438全国成人免费| 日韩在线观看免费网站| 国产激情久久久久| 91精品久久久久久久久久| 亚洲天堂2020| 国内精品久久久久影院优| 久久夜精品va视频免费观看| 2021国产精品视频| 日韩大胆人体377p| 欧美电影免费观看高清完整| 欧美性xxxx在线播放| 最近2019年好看中文字幕视频| 欧美特黄级在线| 日本19禁啪啪免费观看www| 福利视频一区二区| 国产精品av网站| 亚洲国产日韩欧美在线99| 欧美福利视频在线观看| 538国产精品一区二区免费视频| 国产精品丝袜一区二区三区| 91香蕉国产在线观看| 欧美激情视频播放| 91深夜福利视频| 久久久91精品国产一区不卡| 亚洲天堂网站在线观看视频| 69av视频在线播放| 一二美女精品欧洲| 日韩有码视频在线| 国产噜噜噜噜噜久久久久久久久| 欧美裸体xxxx极品少妇| 日韩在线中文字| 成人在线视频福利| 久久精品视频在线| 国产成人精品日本亚洲专区61| 久久久亚洲国产天美传媒修理工| 欧美性xxxxx| 亚洲一区二区中文| 亚洲va久久久噜噜噜久久天堂| 久久久久久av| 2019国产精品自在线拍国产不卡| 成人免费在线视频网址| 欧美日韩在线视频一区二区| 欧美做受高潮电影o| 亚洲男人天堂2023| 欧美成人精品不卡视频在线观看| 久久久精品在线| 久久久999精品| 成人免费激情视频| 国产狼人综合免费视频| 夜夜嗨av一区二区三区四区| 在线精品高清中文字幕| 成人乱人伦精品视频在线观看| 久久九九精品99国产精品| 久久伊人精品视频| 久久国产精品影片| 久久久久亚洲精品成人网小说| 亚洲国产美女精品久久久久∴| 91国产精品视频在线| 狠狠干狠狠久久| 一区二区三区四区在线观看视频| 久久久精品久久| 91国在线精品国内播放| 91视频国产高清| 亚洲综合av影视| 欧美日韩国产在线播放| 俺去亚洲欧洲欧美日韩| 久久成人亚洲精品| 91国产精品91| 国产精品麻豆va在线播放| 九九视频这里只有精品| 国产日韩视频在线观看| 国产女人18毛片水18精品| 欧美成人中文字幕在线| 国产一区欧美二区三区| 亚洲人免费视频| 国产精品扒开腿做爽爽爽男男| 精品欧美国产一区二区三区| 亚洲精品v欧美精品v日韩精品| 日韩最新在线视频| 日韩av网站电影| 久久久久久久久久久久久久久久久久av| 国产亚洲精品美女| 亚洲综合中文字幕在线| 亚洲国产97在线精品一区| 亚洲国产中文字幕在线观看| 日韩在线视频免费观看高清中文| 久久久精品欧美| 欧洲s码亚洲m码精品一区| 中文字幕欧美日韩精品| 久久久久久国产精品三级玉女聊斋| 91精品国产自产在线老师啪| 国产91在线播放| 日韩精品免费一线在线观看| 久久影视免费观看| 国产精品欧美风情| 91免费看片在线| 国产98色在线| 久久久久久久久久国产| 国产精品视频一区二区高潮| 国产精品视频99| 精品视频久久久久久久| 欧美在线中文字幕| 日韩免费av一区二区| 欧美专区在线视频| 国模视频一区二区| 91夜夜未满十八勿入爽爽影院| 欧美韩国理论所午夜片917电影| 日韩午夜在线视频| 91在线精品播放| 国产精品香蕉在线观看| 久久久久久久国产精品视频| 国产午夜精品美女视频明星a级| 最近2019年好看中文字幕视频| 91成人精品网站| 亚洲bt欧美bt日本bt| 国产69精品久久久久99| 91高清在线免费观看| 国产在线98福利播放视频| 精品国产一区二区三区久久久狼| 欧美激情视频网站| 日韩国产欧美区| 国产性色av一区二区| 国产精品久久久久久久av电影| 精品一区精品二区| 国产精品偷伦免费视频观看的| 伊人伊人伊人久久| 日韩av男人的天堂| 国产极品jizzhd欧美| 欧美激情第一页xxx| 福利一区视频在线观看| 亚洲一区二区三区乱码aⅴ蜜桃女| 国产性猛交xxxx免费看久久| 欧美成人精品一区二区| 欧美香蕉大胸在线视频观看| 国产一区二区在线免费| 91精品在线观看视频| 国产成人+综合亚洲+天堂| 色偷偷av一区二区三区| 亚洲国产精久久久久久| 欧美大尺度在线观看| 国产日韩欧美在线观看| 国产精品久久婷婷六月丁香| 久久久欧美精品| 国产精品嫩草视频| 精品久久久久久中文字幕| 日韩免费看的电影电视剧大全| 日韩一区二区福利| 国产91热爆ts人妖在线| 国产精品高清网站| 中文字幕精品国产| 久久久久久999| 亚洲人线精品午夜| 成人免费视频xnxx.com| 热99精品只有里视频精品| 91精品国产综合久久香蕉922| 亚洲国产天堂网精品网站| 久久久久久噜噜噜久久久精品| 国产成人jvid在线播放|