国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 語言 > JavaScript > 正文

javascript設計模式之裝飾者模式

2024-05-06 15:43:57
字體:
來源:轉載
供稿:網友

在js函數開發中,想要為現有函數添加與現有功能無關的新功能時,按普通思路肯定是在現有函數中添加新功能的代碼。這并不能說錯,但因為函數中的這兩塊代碼其實并無關聯,后期維護成本會明顯增大,也會造成函數臃腫。

比較好的辦法就是采用裝飾器模式。在保持現有函數及其內部代碼實現不變的前提下,將新功能函數分離開來,然后將其通過與現有函數包裝起來一起執行。

先來看個比較原始的js版裝飾器模式實現:

var Plane = function(){}Plane.prototype.fire = function(){ console.log('發射普通子彈');}//增加兩個裝飾類,導彈類和原子彈類var MissileDecorator = function(plane){ this.plane = plane;}MissileDecorator.prototype.fire = function(){ this.plane.fire(); console.log('發射導彈');}var AtomDecorator = function(plane){ this.plane = plane;}AtomDecorator.prototype.fire = function(){ this.plane.fire(); console.log('發射原子彈');}var plane = new Plane();console.log(plane);plane = new MissileDecorator(plane);console.log(plane);plane = new AtomDecorator(plane);console.log(plane);plane.fire();/*發射普通子彈發射導彈發射原子彈*/

升級版裝飾器模式,通過為js的Function構造函數添加實例方法before和after來實現。

Function.prototype.before和Function.prototype.after接收一個函數作為參數,這個函數就是新添加的函數,它裝載了新添加的功能代碼。

接下來把當前的this保存起來,這個this指向原函數(Function是js中所有函數的構造器,所以js中的函數都是Function的實例,Function.prototype中的this就指向該實例函數)

然后返回一個'代理'函數,這個代理函數只是結構上像'代理'而已,并不承擔代理的職責(比如控制對象的訪問)。它的工作就是把請求分別轉發給新添加的函數和原函數,且負責保證它們的執行順序,讓新添加的函數在原函數之前執行(前置裝飾 Function.prototype.before; 后置裝飾 Function.prototype.after),從而實現動態裝飾的效果。

// AOP 裝飾函數Function.prototype.before = function(beforefn){ var _self = this;  //保存原函數的引用 return function(){  //返回包含了原函數和新函數的‘代理'函數  beforefn.apply(this, arguments);  //先執行新函數,且保證this不會被劫持,新函數接受的參數也會原封不動的傳入原函數,新函數在原函數之前執行  return _self.apply(this, arguments); //再執行原函數并返回原函數的執行結果,并保證this不被劫持 }}Function.prototype.after = function(afterfn){ var _self = this;  //保存原函數的引用 return function(){  //返回包含了原函數和新函數的‘代理'函數  var ret = _self.apply(this, arguments); //先執行原函數并返回原函數的執行結果,并保證this不被劫持,原函數執行的結果會賦值給ret變量,交由'代理'函數最后return  afterfn.apply(this, arguments);   //再執行新函數,且保證this不會被劫持,新函數接受的參數也會原封不動的傳入原函數,新函數在原函數之前執行    return ret;  }}//定義原函數var print = function(){ console.log('打印原函數執行結果');}print = print.before(function(){ console.log('打印前置裝飾函數的執行結果');})print = print.after(function(){ console.log('打印后置裝飾函數的執行結果');})//執行裝飾后的print函數,為原函數print函數添加的裝飾器對用戶來說看起來是透明的print();//打印結果/*打印前置裝飾函數的執行結果打印原函數執行結果打印后置裝飾函數的執行結果*/            
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 湛江市| 京山县| 丹凤县| 葫芦岛市| 南丰县| 大方县| 汪清县| 呼图壁县| 泰安市| 图们市| 辉南县| 怀宁县| 彭州市| 霸州市| 钟祥市| 绍兴市| 阿合奇县| 丽水市| 本溪| 苍南县| 永善县| 云和县| 宣化县| 平阳县| 固始县| 东乌| 长沙市| 大渡口区| 菏泽市| 盐边县| 定远县| 准格尔旗| 阿巴嘎旗| 汉中市| 河南省| 抚顺县| 吉林省| 运城市| 奈曼旗| 潜山县| 新巴尔虎右旗|