最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

學(xué)習(xí)JavaScript設(shè)計(jì)模式之裝飾者模式

 更新時(shí)間:2016年01月19日 09:55:54   作者:奮飛  
這篇文章主要為大家介紹了JavaScript設(shè)計(jì)模式中的裝飾者模式,對(duì)JavaScript設(shè)計(jì)模式感興趣的小伙伴們可以參考一下

有時(shí)我們不希望某個(gè)類天生就非常龐大,一次性包含許多職責(zé)。那么我們就可以使用裝飾著模式。
裝飾著模式可以動(dòng)態(tài)地給某個(gè)對(duì)象添加一些額外的職責(zé),從而不影響這個(gè)類中派生的其他對(duì)象。
裝飾著模式將一個(gè)對(duì)象嵌入另一個(gè)對(duì)象之中,實(shí)際上相當(dāng)于這個(gè)對(duì)象被另一個(gè)對(duì)象包裝起來(lái),形成一條包裝鏈。

一、不改動(dòng)原函數(shù)的情況下,給該函數(shù)添加些額外的功能

1. 保存原引用

window.onload = function() {
  console.log(1);
};

var _onload = window.onload || function() {};

window.onload = function() {
  _onload();
  console.log(2);
}

問(wèn)題:
(1)必須維護(hù)中間變量
(2)可能遇到this被劫持問(wèn)題
在window.onload的例子中沒(méi)有這個(gè)煩惱,是因?yàn)檎{(diào)用普通函數(shù)_onload時(shí),this也指向window,跟調(diào)用window.onload時(shí)一樣。

2. this被劫持:

var _getElementById = document.getElementById;
document.getElementById = function(id) {
  console.log(1);
  return _getElementById(id);
}

return _getElementById(id); // 報(bào)錯(cuò)“Uncaught TypeError: Illegal invocation”

因?yàn)開(kāi)getElementById是全局函數(shù),當(dāng)調(diào)用全局函數(shù)時(shí),this是指向window的,而document.getElementById中this預(yù)期指向document。

3. 解決this被劫持:

var _getElementById = document.getElementById;
document.getElementById = function(id) {
  console.log(1);
  return _getElementById.call(document, id);
}

二、用AOP裝飾函數(shù)

/* 讓新添加的函數(shù)在原函數(shù)之前執(zhí)行(前置裝飾)*/
Function.prototype.before = function(beforefn) {
  var _self = this;
  return function() {
    beforefn.apply(this, arguments);  // 新函數(shù)接收的參數(shù)會(huì)被原封不動(dòng)的傳入原函數(shù)
    return _self.apply(this, arguments);
  };
};

/* 讓新添加的函數(shù)在原函數(shù)之后執(zhí)行(后置裝飾)*/
Function.prototype.after = function(afterfn) {
  var _self = this;
  return function() {
    var ret = _self.apply(this, arguments);
    afterfn.apply(this, arguments);
    return ret;
  };
};

document.getElementById = document.getElementById.before(function() {
  console.log(1);
});

三、避免污染原型

var before = function(fn, beforefn) {
  return function() {
    beforefn.apply(this, arguments);
    return fn.apply(this, arguments);
  };
};

var after = function(fn, afterfn) {
  return function() {
    var ret = fn.apply(this, arguments);
    afterfn.apply(this, arguments);
    return ret;
  };
};

document.getElementById = before(document.getElementById, function(){
  console.log(1);
});

四、示例–插件式的表單驗(yàn)證

結(jié)合《學(xué)習(xí)JavaScript設(shè)計(jì)模式之策略模式》中的【表單驗(yàn)證】,運(yùn)用到ajax提交數(shù)據(jù)驗(yàn)證,效果很棒!

修改上述before方法

var before = function(fn, beforefn) {
  return function() {
    if(beforefn.apply(this, arguments) === false) {
      // beforefn返回false,直接return,不執(zhí)行后面的原函數(shù)
      return;
    }
    return fn.apply(this, arguments);
  };
};
/* 模擬數(shù)據(jù)驗(yàn)證*/
var validate = function() {
  if(username === "") {
    console.log("驗(yàn)證失?。?);
    return false;
  }
  return true;
}
/* 模擬ajax提交*/
var formSubmit = function() {
  console.log("提交?。?!");
}
username = 1;
formSubmit = before(formSubmit, validate); // 提交!!!
formSubmit();

username = "";
formSubmit = before(formSubmit, validate); // 驗(yàn)證失??!
formSubmit();

五、裝飾者模式和代理模式

相同點(diǎn):這兩種模式都描述了怎么為對(duì)象提供一定程度上的間接引用,它們的實(shí)現(xiàn)部分都保留了對(duì)另外一個(gè)對(duì)象的引用,并且向那個(gè)對(duì)象發(fā)送請(qǐng)求。
區(qū)別:
(1)代理模式:當(dāng)直接訪問(wèn)本地不方便或者不符合需求時(shí),為這個(gè)本體提供一個(gè)替代者。本地定義關(guān)鍵功能,而代理提供或拒絕對(duì)它的訪問(wèn),或者在訪問(wèn)本體之前走一些額外的事情。(其做的事情還是跟本體一樣)
(2)裝飾者模式:為對(duì)象動(dòng)態(tài)加入行為。(一開(kāi)始不能確定對(duì)象的全部功能,實(shí)實(shí)在在的為對(duì)象添加新的職責(zé)和行為)

希望本文所述對(duì)大家學(xué)習(xí)javascript程序設(shè)計(jì)有所幫助。

相關(guān)文章

  • 一文詳解Webpack中Tapable事件機(jī)制

    一文詳解Webpack中Tapable事件機(jī)制

    Webpack?是前端工程化常用的靜態(tài)模塊打包工具,在合適的時(shí)機(jī)通過(guò)?Webpack?提供的?API?改變輸出結(jié)果,使?Webpack?可以執(zhí)行更廣泛的任務(wù),擁有更強(qiáng)的構(gòu)建能力,本文將介紹?Tapable?的基本使用以及底層實(shí)現(xiàn),需要的朋友可以參考下
    2023-11-11
  • JS實(shí)現(xiàn)炫酷輪播圖

    JS實(shí)現(xiàn)炫酷輪播圖

    這篇文章主要為大家詳細(xì)介紹了JS實(shí)現(xiàn)炫酷輪播圖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • Javascript中對(duì)象繼承的實(shí)現(xiàn)小例

    Javascript中對(duì)象繼承的實(shí)現(xiàn)小例

    這篇文章主要介紹了Javascript中對(duì)象繼承的實(shí)現(xiàn),需要的朋友可以參考下
    2014-05-05
  • JavaScript代碼里的判斷小結(jié)

    JavaScript代碼里的判斷小結(jié)

    在JavaScript代碼中,多多少少會(huì)有判斷語(yǔ)句。業(yè)務(wù)越復(fù)雜,邏輯就越復(fù)雜,判斷就越多。今天給大家整理下JavaScript中代碼里常會(huì)用到的那些判斷,有需要的可以參考借鑒。
    2016-08-08
  • 微信小程序自定義底部、頂部、中間、左邊及右邊彈窗

    微信小程序自定義底部、頂部、中間、左邊及右邊彈窗

    這篇文章主要給大家介紹了關(guān)于微信小程序自定義底部、頂部、中間、左邊及右邊彈窗的相關(guān)資料,彈窗是小程序中非常重要的一種互動(dòng)方式,比如用戶注冊(cè)時(shí)錯(cuò)誤提示、優(yōu)惠券領(lǐng)取提示、簽到成功提示等等,需要的朋友可以參考下
    2023-11-11
  • 基于JavaScript實(shí)現(xiàn)輪播圖原理及示例

    基于JavaScript實(shí)現(xiàn)輪播圖原理及示例

    這篇文章主要為大家詳細(xì)介紹了基于JavaScript實(shí)現(xiàn)輪播圖原理及示例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-02-02
  • 在瀏覽器測(cè)試JavaScript的方法小結(jié)

    在瀏覽器測(cè)試JavaScript的方法小結(jié)

    測(cè)試JavaScript代碼是一件很痛苦的事情,很多情況下都是寫(xiě)好代碼不斷刷新測(cè)試,其實(shí)chrome瀏覽器的console下就很方便,這里就為大家簡(jiǎn)單分享一下
    2023-03-03
  • JS實(shí)現(xiàn)處理時(shí)間,年月日,星期的公共方法示例

    JS實(shí)現(xiàn)處理時(shí)間,年月日,星期的公共方法示例

    這篇文章主要介紹了JS實(shí)現(xiàn)處理時(shí)間,年月日,星期的公共方法,結(jié)合實(shí)例形式分析了javascript日期時(shí)間的轉(zhuǎn)換、運(yùn)算相關(guān)操作技巧,需要的朋友可以參考下
    2019-05-05
  • 在網(wǎng)頁(yè)里看flash的trace數(shù)據(jù)的js類

    在網(wǎng)頁(yè)里看flash的trace數(shù)據(jù)的js類

    我的js類jdhcn.js中的一個(gè)flashDebug方法
    2009-01-01
  • 讓瀏覽器DOM元素最后加載的js方法

    讓瀏覽器DOM元素最后加載的js方法

    讓瀏覽器DOM元素最后加載的方法有很多,本例為大家介紹下,通過(guò)js如何實(shí)現(xiàn)
    2014-07-07

最新評(píng)論

碌曲县| 乌拉特前旗| 环江| 固始县| 招远市| 南川市| 方山县| 陈巴尔虎旗| 芦山县| 旺苍县| 子长县| 乌苏市| 辽阳市| 黑河市| 怀来县| 彭阳县| 全州县| 辽阳市| 剑阁县| 吉安县| 西乌珠穆沁旗| 贡山| 靖州| 师宗县| 义马市| 庄河市| 德清县| 南阳市| 林芝县| 河北省| 浦江县| 江门市| 茌平县| 阳泉市| 德惠市| 镇平县| 洪湖市| 长武县| 永平县| 南召县| 南丰县|