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;
})();

也就是说,如果这段代码的作者没有考虑任何特定的用例,我不会感到惊讶,只是觉得在它的方法中引用storeas更清楚store

于 2013-09-22T09:33:59.640 回答
2

该代码的作者可能对此有充分的理由,但从表面上看,这看起来像是草率、幼稚的编码。

恕我直言,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,则需要使用它的全局名称或闭包引用。第二个通常是首选,同样是为了便携性。

于 2013-09-22T09:32:32.130 回答