2017-03-22 3 views
1

私は、次のコード内の変数tmpの点をご理解悩ま抱えている:このスニペットの変数 `tmp`の目的は何ですか?

$.extend($.Widget.prototype, { 
    yield: null, 
    returnValues: { }, 
    before: function(method, f) { 
     var original = this[method]; 
     this[method] = function() { 
      f.apply(this, arguments); 
      return original.apply(this, arguments); 
     }; 
    }, 
    after: function(method, f) { 
     var original = this[method]; 
     this[method] = function() { 
      this.returnValues[method] = original.apply(this, arguments); 
      return f.apply(this, arguments); 
     } 
    }, 
    around: function(method, f) { 
     var original = this[method]; 
     this[method] = function() { 
      var tmp = this.yield; 
      this.yield = original; 
      var ret = f.apply(this, arguments); 
      this.yield = tmp; 
      return ret; 
     } 
    } 
}); 

はなぜ単に関数のローカル変数var yieldを使用していないし、完全にaround方法でtmpを除外?それは何の目的ですか?これは共通のデザインパターンですか?

ありがとうございました。

+0

一時的です。 'f()'の中で 'this.yield'が使われていると思います。これは' original'を参照する必要があります。 – Tushar

+0

はい、 'yield'という名前のvarを使うことができます...' yield'は予約済みのキーワードです - varの名前は意味がありません –

+0

多分this.yield = originalはf.apply( ) 関数。そのため、このデータは一時変数に格納されていました。 – Chinito

答えて

0

明らかに、そのコードは、Extending jQuery UI Widgetsから来ています。これは、いくつかの便利なコンテキストを示しています。その記事では、コードのソースとしてAvoiding Bloat in Widgetsを参照しています。ただし、オリジナルにはtmpという変数はありません。

私はtmpの追加が好きです。元のコードには副作用がありません。周りの機能を使用することを想定している方法を考えてみましょう:またはtmpジャグリングなしで期待通り

YourWidgetObject.existingWidgetClass("around", "click", function(){ 
    console.log("before"); //or any code that you want executed before all clicks 
    yield(); // executes existing click function 
    console.log("after"); //or any code that you want executed after all clicks 
} 

これは動作します。 clickイベントは、イベントの前後に余分なコードを実行するようになりました。

tmpを使用してyieldを復元しないと、オブジェクトのパブリックメソッドyieldが再定義されます。だから、誰かがを使った後にYourWidgetObject.yield()と呼んだという奇妙な考えを持っていたら、最後に適用された既存の方法around(この場合はclick)を実行します。明確化のためのリクエストの後に追加されました

はあなたがすべてでyieldを復元し、またこれをnullに設定しないことを想像してみてください。そして、上記のコードの後に​​、あなたはこれを行う:

YourWidgetObject.existingWidgetClass("before", "focus", function(){ 
    yield(); // executes existing **click** function 
} 

yieldは今、非常に予期しない動作である焦点上のクリック機能を実行します。

tmpで復元するのではなく、yieldをヌルに設定するだけですか?確かに、今のように、それは差をつけません。しかし、他のメソッドを変更したり追加したりする場合は、aroundメソッドが現在の状態を認識しないようにするのが一層賢明です。すなわち、呼び出されたときに常にyieldがnullであることを知る必要はありません。

イベントの周りに物事を置くことは必ずしもそうであるとは限らないので、これは恐ろしいaroundの方法だと思うのですが、あなたは何度も欲しいと思っています。実際のaroundメソッドのほうが賢明なのは、2つのコールバック(1つはイベントの前に、もう1つは後に実行される)を受け入れることです。そうすれば、最初にyieldメソッドを公開する必要はありません。

around: function(method, before, after) { 
    var original = this[method]; 
    this[method] = function() { 
     before(); 
     original(); 
     after(); 
    } 
} 
+0

私はあなたの答えを何度も読んでいて、まだ 'tmp'は不要だと思っています。 'this.yield'は' null'で始まり、常に 'null'に復元されます。誰かが奇妙なアイデアを持ち、それをどう呼ぶことができますか?そのシナリオを説明するための例を教えてください。ありがとう。 –

+0

明確にするために編集されました。 – GertG

+0

優れた判断。このような 'around'ラッパーにとっては、本当に漏れた抽象です。 –

関連する問題