2

次のコードstore.nextIdでは、 がメソッドstore.cacheで使用されています。addなぜだろうと思っていましたthisか?

var store = {
  nextId: 1,

  cache: {},

  add: function(fn) {
    if (!fn.id) {
      fn.id = store.nextId++;
      return !!(store.cache[fn.id] = fn);
    }
  }
};

私の質問に答えてくれた皆さん、ありがとう!

4

3 に答える 3

3

using のセマンティクスは using のセマンティクスとstoreは少し異なりthisます。つまりstore.add、通常の関数として扱う場合 (たとえば、別の関数に引数として渡す場合)、 usingstoreは関数が引き続き を参照することを意味しますがstore、 usingthisは代わりに、グローバル オブジェクトを参照します。

もちろん、トレードオフは、このメソッドが、その変数によって最初に識別されたオブジェクトではなく、変数によって現在識別されてaddいるオブジェクトを常に参照することです。このメソッドが実際には常に同じオブジェクトを参照すると仮定すると、両方のアプローチの利点を得る方法は、すぐに呼び出される関数式を使用することです。store

var store = (function () {
    var store = {
        ...  // exactly as defined in the code you posted, but now 'store'
             // refers to the *local* variable 'store', which can never change
    };
    return store;
})();

storeとはいえ、このコードの作成者が特定のユースケースを念頭に置いていなくても、私は驚くことではありませんstore

于 2013-09-22T09:33:59.640 に答える
2

そのコードの作成者にはこれに十分な理由があるかもしれませんが、一見すると、ずさんで素朴なコーディングのように見えます。

IMHO、JSオブジェクト内の関数は、そのオブジェクトが認識されている外部変数名(または名前)に依存するべきではありません。

コードが使用されている場合、thisこれを行うことが可能になります:

var storeCopy = store;
store = null;
storeCopy.add(...);      // still works

への内部参照があるためstore、このコードをモジュール化して再利用することはできません。

于 2013-09-22T09:33:08.603 に答える
1

この特定のケース (スコープ内にある名前変数にメソッドがある場合) では、thisまたは正常にstore動作します。

移植性が高いため、私は好みthisます。オブジェクト定義を移動したり、名前storeを変更したりでき、その中のコードを変更する必要はありません。

ただし、場合によっては、グローバル名を使用する理由がわかる場合があります。たとえば、別のオブジェクトにバインドされるイベント ハンドラーとして割り当てる関数を作成する場合です。関数が別のオブジェクトにバインドされている場合、それはthisその別のオブジェクトを参照することを意味します。への参照が必要な場合はstore、そのグローバル名またはクロージャ参照を使用する必要があります。移植性のために、通常は 2 番目の方法が好まれます。

于 2013-09-22T09:32:32.130 に答える