ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript デコレータ パターン

JavaScript デコレータ パターン

高洛峰
高洛峰オリジナル
2017-01-19 15:51:271230ブラウズ

従来のオブジェクト指向言語では、オブジェクトに機能を追加するために継承がよく使用されますが、継承によって問題が発生する可能性があります。親クラスが変更されると、そのすべてのサブクラスもそれに応じて変更されます。

JavaScript スクリプトが実行されると、オブジェクト (またはそのプロトタイプ) に動作を追加すると、オブジェクトのすべてのインスタンスに影響します。

デコレーターは、メソッドのオーバーロードによって実装される、新しい機能を追加します。特定の目的を達成するために、装飾されたオブジェクトの前後に独自の動作を追加できる形式。

デコレーター パターンは、装飾される各関数を別の関数に配置し、その関数を使用して装飾される既存の関数オブジェクトをラップするため、特別な動作が必要な場合に、既存の関数に動的に関数を追加する方法です。実行するために、呼び出し元のコードは、装飾関数を選択的かつ連続的に使用して、必要に応じてオブジェクトをラップできます。利点は、クラス (関数) と装飾関数の中核となる役割が分離されていることです。

次のようにツール関数を定義できます:

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 のパラメータは、元の関数に新しい関数を拡張する新しい関数 (装飾を追加する) です。それらの唯一の違いは実行順序です。関数プロトタイプを汚染したくない場合は、次の方法を使用できます:

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

例: CSRF 攻撃を防ぐために HTTP リクエストにパラメータを追加する

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 中国語 Web サイトをサポートしていただければ幸いです。

JavaScript デコレーター パターンに関連するその他の記事については、PHP 中国語 Web サイトに注目してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。