在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);
}
}
};
感谢所有回答我问题的人!
答案 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)
在这种特定情况下(您在范围内的名称变量上有方法),this
或store
工作正常。
我更喜欢this
,因为它更具可移植性 - 您可以移动对象定义或重命名store
,而不必更改其中的任何代码。
但是,有时您可能会看到拥有全局名称的理由。例如,如果您要创建一个函数,您将其指定为事件处理程序,它将绑定到另一个对象。当函数绑定到不同的对象时,这意味着this
将引用该另一个对象。如果需要返回store
的引用,则需要使用它的全局名称或闭包引用。第二种通常是首选,同样是为了便携性。