0

私はevent.jsでのonce()の実装を見ています:

EventEmitter.prototype.once = function(type, listener) {
  if ('function' !== typeof listener) {
    throw new Error('.once only takes instances of Function');
  }

  var self = this;
  function g() {
    self.removeListener(type, g);
    listener.apply(this, arguments);
  };

  g.listener = listener;
  self.on(type, g);

  return this;
};

あなたがすることを覚えているsome_object.once('on', function(){ console.log(this); } );

一時関数g()には。がありself.removeListener(type,g)ます。そうでなければ、g()のコンテキストが間違っているからだと思います。しかし、その後の行では、変数thisはで使用されlistener.apply(this, arguments);ますが...これはグローバルコンテキストをに渡すのではありませんlistener(arguments)?

次に少し下がると、self.on代わりに実行されthis.onます。

今...私は混乱しています。私はJavascriptにかなり慣れていませんが、それでもコンテキストに混乱しています。しかし、このコードは私にバナナを駆り立てています...誰かがここで私を教えてくれませんか?

ありがとう、

メルク。

4

1 に答える 1

1

あなたの例でthislikeのコピーを使用する理由は、特定の関数呼び出しで必要なように設定されない場合、保存されたコピーを参照して常にアクセスできるためです。selfthisself

Javascript では、またはthisで明示的に設定されていない限り、呼び出しコンテキストによって設定されます。 .call().apply()

通常の関数呼び出しではthis、グローバル オブジェクトに設定されます。

のようなメソッド呼び出しx.once()によりthisonce()メソッド内で object が設定されますx

あなたの特定のケースでg()は、コールバック関数として使用されています。そのためthis、そのコールバック関数の呼び出し元で使用されるコンテキストによって設定されます。ただし、そのコンテキストが望ましくなく、オブジェクトにg()アクセスしたい場合は、存在するクロージャーに保存されている参照を使用できます。関数に保存された参照がないと、目的のオブジェクトにアクセスできない可能性があります関数内で別の値に設定されている可能性があるためです。EventEmitterselfg()selfg()thisg()

この.once()メソッドの意図に従えば、を呼び出すときに が必要に応じて設定されるため、self参照の理由.on()がわかりません。その場合、必要に応じて設定されていないコールバックが使用されたときに安全に機能するのは、従われている規則にすぎない可能性があります (この特定のコードでは厳密にはそうではありませんが)。thisg()this

self.on()の代わりに呼び出すことについてthis.on()は、実行に違いはありません。の値はthis、特定の関数コンテキスト内では変化しません。ローカル変数に割り当ててからローカル変数を参照するライブラリがいくつかあります。これはthis、主に、最小化時にローカル変数の名前を 1 バイト値に変更できるため、最小化時に数バイトを節約できるためですが、値のthis名前を変更することはできません。

これは、より長い議論を含む関連記事です: What is the value of var me = this;

于 2012-05-20T04:49:38.137 に答える