首頁 >web前端 >js教程 >JavaScript裝飾者模式

JavaScript裝飾者模式

高洛峰
高洛峰原創
2017-01-19 15:51:271240瀏覽

在傳統的物件導向語言中,為物件添加功能常常使用繼承的方式,但繼承的方式會帶來問題:當父類別改變時,他的所有子類別都會隨之改變。

當JavaScript腳本運行時,在一個物件中(或他的原型上)增加行為會影響該物件的所有實例, 

裝飾者是一種實現繼承的替代方案,它透過重載方法的形式添加新功能,該模式可以在被裝飾者前面(before)或後面(after)加上自己的行為以達到特定的目的。

裝飾者模式是為已有功能動態地添加更多功能的一種方式,把每個要裝飾的功能放在單獨的函數裡,然後用該函數包裝所要裝飾的已有函數對象,因此,當需要執行特殊行為的時候,呼叫程式碼就可以根據需要選擇性地、依序地使用裝飾功能來包裝物件。優點是把類別(函數)的核心職責和裝飾功能區分開了。 

我們可以定義工具函數,如下:

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);
    afterFn.apply(this,arguments);
    return ret;
  }
};

這裡的參數beforeFn、afterFn即為要為原始函數擴展新功能的新函數(添加裝飾),它們的唯一區別是執行順序的不同。如果不想污染Function的原型,可以用下面的方法:

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;
  }
};

例子:給HTTP請求中帶上一個參數來防止CSRF攻擊

var ajax = function (type, url, param) {
  console.log(param); //发送ajax请求代码略...
};
var beforeFn = function (type, url, param) {
  param.Token = 'Token';
};
ajax = ajax.before(beforeFn);
ajax('get','http://...com/userinfo',{name:'SuFa'});
//{ name: 'SuFa', Token: 'Token' }

透過給ajax函數動態裝飾上Token參數,而不是直接在原函數上修改參數,保​​證了ajax函數仍然是一個純淨的函數,提高了它的可復用性,它可在無需做​​任何修改的情況下直接拿到別的項目中使用。

範例:表單驗證(把驗證輸入和表單提交的程式碼分開離開來,然後動態的把驗證輸入功能裝飾到表單提交之前,這樣一來,我們就可以把驗證輸入部分寫成一個插件的形式,用在不同的項目)

//验证输入函数
var validata = function () {
  if(username.value === ''){
    alert('用户名不能为空');
    return false;
  }
  if(password.value === ''){
    alert('密码不能为空');
    return false;
  }
};
//表单提交函数
var formSubmit = function () {
  var param = {
    username: username.value,
    password: password.value
  };
  ajax('http://xxx.com/login',param);
};
 
formSubmit = formSubmit.before(validata);
submitBtn.onclick = function(){
  formSubmit();
};

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持PHP中文網。

更多JavaScript裝飾者模式相關文章請關注PHP中文網!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn