为什么在对象的方法中使用对象名称而不是这个?

时间:2013-09-22 09:27:00

标签: javascript

store.nextId方法中使用了以下代码store.cacheadd。我想知道为什么不this

var store = {
  nextId: 1,

  cache: {},

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

感谢所有回答我问题的人!

3 个答案:

答案 0 :(得分:3)

使用store的语义与使用this的语义略有不同,因为如果您将store.add视为常规函数(例如,将其作为参数传递给不同的函数),然后使用store意味着该函数仍将引用store,而使用this将导致它引用全局对象。

当然,权衡是这个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更为明确甚至在其方法中。

答案 1 :(得分:2)

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

恕我直言,JS对象中的函数永远不应该依赖于该对象所知的外部变量名称(或多个名称)。

如果代码使用this,则可以执行此操作:

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

store的内部引用到位后,此代码无法模块化以便重复使用。

答案 2 :(得分:1)

在这种特定情况下(您在范围内的名称变量上有方法),thisstore工作正常。

我更喜欢this,因为它更具可移植性 - 您可以移动对象定义或重命名store,而不必更改其中的任何代码。

但是,有时您可能会看到拥有全局名称的理由。例如,如果您要创建一个函数,您将其指定为事件处理程序,它将绑定到另一个对象。当函数绑定到不同的对象时,这意味着this将引用该另一个对象。如果需要返回store的引用,则需要使用它的全局名称或闭包引用。第二种通常是首选,同样是为了便携性。