JavaScript デコレータ パターン

高洛峰
リリース: 2017-01-19 15:51:27
オリジナル
1230 人が閲覧しました

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

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 サイトに注目してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!