當前位置:
首頁 >
前端技术
> javascript
>内容正文
javascript
JavaScript学习笔记(四十四) 装饰器
生活随笔
收集整理的這篇文章主要介紹了
JavaScript学习笔记(四十四) 装饰器
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
裝飾器模式(Decorator)
在裝飾器模式中,可以在運行時給一個對象動態(tài)的添加額外的功能。當和靜態(tài)類打交道的時候(static classes),這可能是一個挑戰(zhàn)。但在JavaScript中,對象是可變的,所以給對象添加額外功能的的過程在JavaScript中本身就不是問題。裝飾器一個方便的功能就是期望行為(expected behavior)的定制和配置。你從你的簡單對象開始,只有一些基礎(chǔ)功能。然后你從一個可訪問的包裝器池中挑出那些你想用來增強你的簡單對象的包裝器并按一定順序裝飾,如果順序是重要的。
用法(Usage)
讓我們看一下這個模式的一個示例用法。假設(shè)你正在致力于一個賣東西的web程序。每筆新的銷售(new sale)記錄是一個sale對象。這個sale“知道”這個條目(item)的價格并可以通過調(diào)用sale.getPrice()方法返回。取決于這個情況,你可以開始用額外的功能裝飾這個對象。想象一下這個場景,銷售的顧客在加拿大魁北克省(加拿大魁北克省)。這種情況下,購買者需要支付聯(lián)邦稅(federal tax)和魁北克省稅(provincial Québec tax)。遵循裝飾器模式,你將會說你用一個聯(lián)邦稅裝飾器和一個魁北克省稅裝飾器“裝飾”這個對象。你也可以用一個價格格式化功能裝飾這個對象。這個場景可能看起來像下面這樣: var sale = new Sale(100); // the price is 100 dollars sale = sale.decorate('fedtax'); // add federal tax sale = sale.decorate('quebec'); // add provincial tax sale = sale.decorate('money'); // format like money sale.getPrice(); // "$112.88" 在其它場景中,購買者可能在一個沒有省稅的省,并且你也可能想用加幣(Canadian dollars)格式化價格,那么你可以這樣做: var sale = new Sale(100); // the price is 100 dollars sale = sale.decorate('fedtax'); // add federal tax sale = sale.decorate('cdn'); // format using CDN sale.getPrice(); // "CDN$ 105.00" 正如你看到的,這是一種在運行時靈活添加功能和調(diào)整對象的方法。讓我們看一下如何實現(xiàn)這種模式。實現(xiàn)(Implementation)
實現(xiàn)裝飾器模式的一個方法是每個裝飾器都是一個對象包含了應(yīng)該被重寫的方法。實際上每個裝飾器都繼承至前一個裝飾器裝飾之后的增強對象。每個被裝飾的方法將調(diào)用在uber(繼承的對象)上相同的方法且獲取值并額外做一些處理。最終的影響就是當你在第一個示例中調(diào)用sale.getPrice(),你正在調(diào)用money裝飾器的方法(見圖7-1),因為每個被裝飾的方法首先調(diào)用parent的方法,money的getPrice()首先調(diào)用 quebec的getPrice()方法,這個方法再輪流調(diào)用fedtax的getPrice()等。這條鏈一直到最初的沒包裝的Sale()構(gòu)造方法實現(xiàn)的getPrice()方法。
這是從構(gòu)造方法和原型開始的方法: function Sale(price) {this.price = price || 100; } Sale.prototype.getPrice = function() {return this.price; }; 所有將被實現(xiàn)的裝飾器對象將被作為構(gòu)造方法屬性的屬性: Sale.decorators = {}; 讓我們看一個裝飾器的例子。它是一個實現(xiàn)了自定義的getPrice()方法的對象。記住這個方法首先從parent方法獲得值然后修改那個值: Sale.decorators.fedtax = {getPrice: function() {var price = this.uber.getPrice();price += price * 5 / 100;return price;} }; 類似的我們可以實現(xiàn)其它的裝飾器,需要多少實現(xiàn)多少。它們可以作為核心Sale()的功能擴展,像插件一樣實現(xiàn)(implemented like plugins)。它們甚至可以“存活”在額外的文件中,可以被第三方開發(fā)者開發(fā)和共享: Sale.decorators.quebec = {getPrice: function() {var price = this.uber.getPrice();price += price * 7.5 / 100;return price;} }; Sale.decorators.money = {getPrice: function() {return "$" + this.uber.getPrice().toFixed(2);} }; Sale.decorators.cdn = { getPrice: function() { return "CDN$ " + this.uber.getPrice().toFixed(2); } }; 最后讓我們看一下“神奇(magic)”的decorate()方法,它將所有部分都連接在一起。 記住它將會像這樣被調(diào)用: sale = sale.decorate('fedtax'); 這個"fedtax"字符串將相當于Sale.decorators.fedtax實現(xiàn)的對象。新的被裝飾的對象newobj將會繼承我們現(xiàn)有的對象(最初的對象,或在上一個裝飾器添加之后的對象),就是this對象。為了做到繼承這部分,讓我們使用前面提到過的臨時構(gòu)造函數(shù)模式。我們也設(shè)置newobj的uber屬性,所以child可以訪問到parent。然后從裝飾器復(fù)制所有的其它屬性到新的被裝飾的對象newobj。最后newobj被返回,在我們的示例中,它將會成為新的被更新的sale對象:
Sale.prototype.decorate = function(decorator) {var F = function() {},overrides = this.constructor.decorators[decorator],i,newobj;F.prototype = this;newobj = new F();newobj.uber = F.prototype;for (i in overrides) {if (overrides.hasOwnProperty(i)) {newobj[i] = overrides[i];}}return newobj; };
?
轉(zhuǎn)載于:https://www.cnblogs.com/pangblog/p/3285464.html
總結(jié)
以上是生活随笔為你收集整理的JavaScript学习笔记(四十四) 装饰器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HttpApplication 事件执行
- 下一篇: 扣图方法