欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

Javascript設計模式之裝飾者模式的示例分析-創(chuàng)新互聯(lián)

這篇文章主要介紹了Javascript設計模式之裝飾者模式的示例分析,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

成都創(chuàng)新互聯(lián)公司是一家專注于成都做網(wǎng)站、網(wǎng)站設計與策劃設計,凌海網(wǎng)站建設哪家好?成都創(chuàng)新互聯(lián)公司做網(wǎng)站,專注于網(wǎng)站建設10余年,網(wǎng)設計領域的專業(yè)建站公司;建站業(yè)務涵蓋:凌海等地區(qū)。凌海做網(wǎng)站價格咨詢:13518219792

JavaScript是什么

JavaScript是一種直譯式的腳本語言,其解釋器被稱為JavaScript引擎,是瀏覽器的一部分,JavaScript是被廣泛用于客戶端的腳本語言,最早是在HTML網(wǎng)頁上使用,用來給HTML網(wǎng)頁增加動態(tài)功能。

一、前言:

裝飾者模式(Decorator Pattern):在不改變原類和繼承的情況下動態(tài)擴展對象功能,通過包裝一個對象來實現(xiàn)一個新的具有原對象相同接口的新的對象。

裝飾者模式的特點:

1. 在不改變原對象的原本結構的情況下進行功能添加。

2. 裝飾對象和原對象具有相同的接口,可以使客戶以與原對象相同的方式使用裝飾對象。

3. 裝飾對象中包含原對象的引用,即裝飾對象是真正的原對象經(jīng)過包裝后的對象。

二、Javascript裝飾者模式詳解:

描述:

裝飾者模式中,可以在運行時動態(tài)添加附加功能到對象中。當處理靜態(tài)類時,這可能是一個挑戰(zhàn)。在Javascript中,由于對象是可變的,因此,添加功能到對象中的過程本身并不是問題。

裝飾者模式的一個比較方便的特征在于其預期行為的可定制和可配置特性??梢詮膬H具有一些基本功能的普通對象開始,然后從可用裝飾資源池中選擇需要用于增強普通對象的哪些功能,并且按照順序進行裝飾,尤其是當裝飾順序很重要的時候。

實現(xiàn)裝飾者模式的其中一個方法是使得每個裝飾者成為一個對象,并且該對象包含了應該被重載的方法。每個裝飾者實際上繼承了目前已經(jīng)被前一個裝飾者進行增強后的對象。每個裝飾方法在“繼承的對象”上調(diào)用了同樣的方法并獲取其值,此外它還繼續(xù)執(zhí)行了一些操作。

先上實例1:

//需要裝飾的類(函數(shù))
function Macbook() {
 this.cost = function () {
  return 1000;
 };
} 
//計算商品的包裝費
function PackagingFee(macbook) {
 this.cost = function () {
  return macbook.cost() + 75;
 };
}
//計算商品的運費
function Freight(macbook) {
 this.cost = function () {
  return macbook.cost() + 300;
 };
} 
//計算商品的保險費用
function Insurance(macbook) {
 this.cost = function () {
  return macbook.cost() + 250;
 };
}
// 用法
var myMacbook = new Insurance(new Freight(new PackagingFee(new Macbook())));
console.log(myMacbook.cost());//1625

我們簡單的分析下上面的代碼,上面的代碼中,一共定義了四個函數(shù)(其中一個需要修飾的函數(shù),三個用于修飾的函數(shù))。

然后,聲明一個變量myMacbook指向new出來的Insurance對象,Insurance對象的形參指向new出來的Freight對象,F(xiàn)reight對象的形參指向new出來的PackagingFee對象,PackagingFee對象的形參指向new出來的Macbook對象。

接下來,調(diào)用myMacbook的cost方法。從上面的分析,我們可以得出 myMacbook.cost()的值等于(Freight對象的cost方法+250),F(xiàn)reight對象的cost方法等于(PackagingFee對象的cost方法+300),PackagingFee對象的cost方法等于(Macbook對象的cost方法+75)。

所以最終的結果是:myMacbook.cost()的值 = 250 + (300 + (75 + 1000)) = 1625。

// 用法
var myMacbook = new Insurance(new Freight(new PackagingFee(new Macbook())));
console.log(myMacbook.cost());//1625 
//上面的代碼等價于下面拆分后的代碼,或許拆分后代碼你更能看出前后的邏輯性
var macbook = new Macbook();
var package = new PackagingFee(macbook);
var freight = new Freight(package);
var myMacbook = new Insurance(freight);
//當然,如果你不想聲明這么多變量(macbook、package、freight),只用一個變量也是可以的
var macbook = new Macbook();
macbook = new PackagingFee(macbook);
macbook = new Freight(macbook);
var myMacbook = new Insurance(macbook);

再看看實例2:

function ConcreteClass() {
 this.performTask = function () {
  this.preTask();
  console.log('doing something');
  this.postTask();
 };
}
function AbstractDecorator(decorated) {
 this.performTask = function () {
  decorated.performTask();
 };
}
function ConcreteDecoratorClass(decorated) {
 this.base = AbstractDecorator;
 this.base(decorated);// add performTask method
 decorated.preTask = function () {
  console.log('pre-calling..');
 };
 decorated.postTask = function () {
  console.log('post-calling..');
 };
}
var concrete = new ConcreteClass();
var decorator1 = new ConcreteDecoratorClass(concrete);
decorator1.performTask();
//pre-calling..
//doing something
//post-calling..

實例2實際上和實例1是非常類似的,我們來簡單分析下吧。首先,實例2中定義了三個函數(shù),然后聲明了兩個變量concrete和decorator1,最后調(diào)用了decorator1的performTask方法。

粗看一眼,ConcreteDecoratorClass里面好像并沒有performTask方法。我們先來分析下面的兩行代碼:

var concrete = new ConcreteClass(); //聲明一個變量concrete指向new出來的ConcreteClass對象
var decorator1 = new ConcreteDecoratorClass(concrete); //聲明一個變量decorator1指向new出來的ConcreteDecoratorClass對象,并傳入變量concrete作為形參

然后,我們再來逐行分析下ConcreteDecoratorClass函數(shù)里面的代碼:

this.base = AbstractDecorator; //定義一個當前對象(decorator1)的base屬性,并指向函數(shù)AbstractDecorator
this.base(decorated); //調(diào)用base屬性指向的函數(shù),也就是調(diào)用AbstractDecorator函數(shù),同時傳入形參decorated,形參decorated指向new出來的ConcreteClass對象

說到這里,好像還是沒有分析出ConcreteDecoratorClass函數(shù)里面有performTask方法,重點是看 "this"!

ConcreteDecoratorClass函數(shù)中的this指向new出來的ConcreteDecoratorClass對象(也就是和decorator1指向同一個對象);

AbstractDecorator函數(shù)里面的this關鍵是看哪個對象來調(diào)用這個函數(shù),this就指向哪個對象(從代碼 “this.base = AbstractDecorator; this.base(decorated);” 中我們可以看出是new出來的ConcreteDecoratorClass對象在調(diào)用AbstractDecorator函數(shù)),所以AbstractDecorator函數(shù)里面的this指向new出來的ConcreteDecoratorClass對象(也和decorator1指向同一個對象)。

總結下來,我們會發(fā)現(xiàn),在上面的代碼中,不管是ConcreteDecoratorClass函數(shù)里面的this,還是AbstractDecorator函數(shù)里面的this,都指向new出來的ConcreteDecoratorClass對象。

所以,當我們執(zhí)行decorator1.performTask()時,它會繼續(xù)執(zhí)行匿名函數(shù)中的代碼(decorated.performTask();),匿名函數(shù)中的decorated形參指向new出來的ConcreteClass對象,并執(zhí)行該對象的performTask方法。

最后看看實例3:

var tree = {};
tree.decorate = function () {
 console.log('Make sure the tree won\'t fall');
}; 
tree.getDecorator = function (deco) {
 tree[deco].prototype = this;
 return new tree[deco];
}; 
tree.RedApples = function () {
 this.decorate = function () {
  this.RedApples.prototype.decorate(); // 第7步:先執(zhí)行原型(這時候是Angel了)的decorate方法
  console.log('Add some red apples'); // 第8步 再輸出 red
  // 將這2步作為RedApples的decorate方法
 }
};
tree.BlueApples = function () {
 this.decorate = function () {
  this.BlueApples.prototype.decorate(); // 第1步:先執(zhí)行原型的decorate方法,也就是tree.decorate()
  console.log('Put on some blue apples'); // 第2步 再輸出blue
  // 將這2步作為BlueApples的decorate方法
 }
}; 
tree.Angel = function () {
 this.decorate = function () {
  this.Angel.prototype.decorate(); // 第4步:先執(zhí)行原型(這時候是BlueApples了)的decorate方法
  console.log('An angel on the top'); // 第5步 再輸出angel
  // 將這2步作為Angel的decorate方法
 }
};
tree = tree.getDecorator('BlueApples'); // 第3步:將BlueApples對象賦給tree,這時候父原型里的getDecorator依然可用
tree = tree.getDecorator('Angel'); // 第6步:將Angel對象賦給tree,這時候父原型的父原型里的getDecorator依然可用
tree = tree.getDecorator('RedApples'); // 第9步:將RedApples對象賦給tree
tree.decorate(); // 第10步:執(zhí)行RedApples對象的decorate方法
//Make sure the tree won't fall
//Add blue apples
//An angel on the top
//Put on some red apples

實例3看起來很復雜,實際上分析邏輯還是和前面兩個實例一樣,我們可以看出實例3中一共聲明了5個函數(shù)表達式。我們重點分析下下面的代碼:

//tree.getDecorator('BlueApples')返回new出來的tree.BlueApples的實例對象,并將該對象賦值給空的tree對象
tree = tree.getDecorator('BlueApples'); //new出來的tree.BlueApples的實例對象的原型指向 --> 空對象tree 
//tree.getDecorator('Angel')返回new出來的tree.Angel的實例對象(這行代碼中的第二個tree已經(jīng)是上面一行代碼運行結果后的tree.BlueApples的實例對象)
tree = tree.getDecorator('Angel'); //new出來的tree.Angel的實例對象的原型指向 --> tree.BlueApples的實例對象
//tree.getDecorator('RedApples')返回new出來的tree.RedApples的實例對象(這行代碼中的第二個tree已經(jīng)是上面一行代碼運行結果后的tree.Angel的實例對象)
tree = tree.getDecorator('RedApples'); //new出來的tree.RedApples的實例對象的原型指向 --> tree.Angel的實例對象
//調(diào)用tree.decorate(),這里的tree已經(jīng)是new出來的tree.RedApples的實例對象了。
//tree.RedApples的實例對象的decorate屬性方法里面的第一行代碼是 “this.RedApples.prototype.decorate()”
//結合上面的分析可以得出以下的原型鏈結構:
//this.RedApples.prototype --> tree.Angel;
//tree.Angel.prototype --> tree.BlueApples;
//tree.BlueApples.prototype --> 空對象tree
tree.decorate();

分析到這里,就不難知道最后的輸出結果了。

感謝你能夠認真閱讀完這篇文章,希望小編分享的“Javascript設計模式之裝飾者模式的示例分析”這篇文章對大家有幫助,同時也希望大家多多支持創(chuàng)新互聯(lián)建站,關注創(chuàng)新互聯(lián)網(wǎng)站建設公司行業(yè)資訊頻道,更多相關知識等著你來學習!

另外有需要云服務器可以了解下創(chuàng)新互聯(lián)建站chinadenli.net,海內(nèi)外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。

本文名稱:Javascript設計模式之裝飾者模式的示例分析-創(chuàng)新互聯(lián)
當前鏈接:http://chinadenli.net/article34/dhpcse.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設計公司、關鍵詞優(yōu)化網(wǎng)站策劃、微信小程序移動網(wǎng)站建設、定制開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都app開發(fā)公司