よく知られている実装で私に合わないものは何ですか?
Googleの最初のリンクで提供される実装は、Pythonの場合とは異なります。 多くの記事では、オブジェクトを作成し、そのフィールドに関数を入力し、これらのフィールドを使用して装飾を行わないことを提案しています。
最初のページには、私のものと同様の方法を使用するリンクがいくつかあります。
さらに多くの実装がありますが、それらは私には興味がありません。
私の観点から最も正しいことをお話しします。
通常のデコレータ
では、デコレータとは何ですか?
デコレータは、関数の引数関数を追加する関数です。
Pythonの例:
def superfunc(n=2): print("Megclosure created") def clos(func): print("Megclosure used") def clos1(*args, **kwargs): print("Megclosured function",func.__name__) res = func(*args, **kwargs) return (res**n) return clos1 return clos def a(par): return par+9; b = (superfunc())(a) @superfunc(3) def c(txt): return len(txt)+1 print ( b(1),c("abc"*3))
ここで何をしているの?
ここで、必要なことを実行し、装飾された関数を呼び出す別の関数を作成する関数を作成します。
JavaScriptでどのようになりますか
したがって、関数を呼び出し、関数と、場合によっては追加のパラメーターを渡して、装飾されていない関数bを取得します。
function decorator(){ ..... } ..... function a(){ ...... } ...... var b=decorator(a, arg1, arg2,....., argN);
。
ライブラリの 1つからコードを渡します 。
function withVars(f, variables) { var args = Array.prototype.slice.call(arguments, 1);// , , return function () {// f args, var p = arguments;// arguments ... Array.prototype.push.apply(p, args);//... p f.apply(this, p);// f this p } };
そして適用:
function a(){ var str =""; for(var i=0;i<arguments.length;i++){ str+=arguments[i]+" "; } alert(str); } a(1,2,4,5,"six");//1 2 3 4 5 six var b=withVars(a,4,8,15,16,23,42); b(1,2,4,5,"six");//1 2 3 4 5 six 4 8 15 16 23 42
その結果、数行のコードで強力な効果が得られます。
手首を軽くたたくだけで、パラメーターを最初に追加するように機能をやり直すことができます。 これを行うには、単に置き換える
Array.prototype.push.apply(p, args); f.apply(this, p);
に
Array.prototype.push.apply(args,p); f.apply(this, args);
。
可能な用途
- callback1からcallback2を、callback2からcallback3を呼び出すなど、同時に、あるコールバックから別のコールバックにデータを転送する必要があるとします。 イベントソースに追加情報を渡すことはできません。 たとえば、GM_xmlhttpRequestを使用する場合。 要するに、イベントのソースは私たちから隠されており、呼び出し可能な関数が突き出ていますが、コールバックに送信するための任意の情報は保存されていません。 多くのイベントがあり、それらは「並行して」発生するため、変数の作成はオプションではありません。
次に、これを行います。
function cb1(evt){ ....... GM_xmlhttpRequest({ method: "GET", url: url2, onload: withVars(cb2,processed2) }); } function cb2(evt){ ....... GM_xmlhttpRequest({ method: "GET", url: url3, onload: withVars(cb3,processed3) }); } function cb3(evt){ ....... GM_xmlhttpRequest({ method: "GET", url: url4, onload: withVars(cb4,processed4) }); } function cb3(evt){ ..... } GM_xmlhttpRequest({ method: "GET", url: url1, onload: cb1 });
ソリューションは多くの場合よりも優れています。
- データ検証。
たとえば、関数引数のタイプと特定のフォーマット文字列との対応を確認するデコレータを作成し、一致しない場合は変換/エラーをスローします。
その後、次のようなコードを記述できます。
var mult=fstrValidate(function(a,b){ return a*b; },"%d%d");
- 関数の実行頻度を制限する
- 便利。 多くの場合、デコレータを使用したコードは、よりきれいで、より美しく、より効率的です。
- アプリケーションはあなたの想像力によって制限されます。 問題を「直接」解決したくない/ lyい解決したくない場合は、デコレータを使用して解決できます。
何を読む
JavaScript.ru-クロージャー
引数-MDN
適用-MDN
PS招待してくれたUFOに感謝します。
UPD1:いくつかの用途が追加されました。
UPD2:コードをわずかに修正