考虑以下两个功能,
// function
var returnObject = function() {
var values = [];
return {
sum: function(addend) {
var toReturn = 0;
if (addend) {
values.push(addend);
}
values.forEach(function(el) {
toReturn += el;
});
return toReturn;
}
}
};
// immediately executed function
var returnImmediatelyExecutedFunction = (function() {
var values = [];
return {
sum: function(addend) {
var toReturn = 0;
if (addend) {
values.push(addend);
}
values.forEach(function(el) {
toReturn += el;
});
return toReturn;
}
}
}());
我有一个" eeeergh!脑&#34!;关于这一点的时刻,但我不明白为什么returnObject
每次使用时都返回一个唯一的闭包状态,但returnImmediatelyExecutedFunction
返回相同的状态。
考虑以下内容的输出:
var summer1 = returnImmediatelyExecutedFunction;
summer1.sum(2);
summer1.sum(4);
summer1.sum(8);
console.log(summer1.sum());
var summer2 = returnImmediatelyExecutedFunction;
summer2.sum(2);
summer2.sum(4);
summer2.sum(8);
console.log(summer2.sum());
var summer3 = returnObject();
summer3.sum(2);
summer3.sum(4);
summer3.sum(8);
console.log(summer3.sum());
var summer4 = returnObject();
summer4.sum(2);
summer4.sum(4);
summer4.sum(8);
console.log(summer4.sum());
输出:
14
28 // why not 14?
14
14
答案 0 :(得分:2)
通常,您的returnImmediatelyExecutedFunction
是对封闭状态的单一调用的引用,因此每次使用该引用都将访问相同的状态。
否则,每次调用returnObject
都会对返回的函数及其封闭状态进行新的调用。
请注意,您的returnImmediatelyExecutedFunction
在语义上也等同于:
var returnImmediatelyExecutedFunction = returnObject();
即。它只是一个实例本身。所以给出:
var summer1 = returnImmediatelyExecutedFunction;
var summer2 = returnImmediatelyExecutedFunction;
var summer3 = returnObject();
var summer4 = returnObject();
应该轻而易举地指出summer1
和summer2
是同一个实例。
答案 1 :(得分:1)
通过注释创建和使用对象/范围的位置可能更容易看到:
returnObject = ... /* No scope created, just a function is given a name */
returnImmediatelyExecutedFunction = ... /* Create scope A */
var summer1 = returnImmediatelyExecutedFunction; /*A*/
summer1.sum(2); /*A*/
summer1.sum(4); /*A*/
summer1.sum(8); /*A*/
console.log(summer1.sum()); /*A*/
var summer2 = returnImmediatelyExecutedFunction; /*Still A*/
summer2.sum(2); /*Still A*/
summer2.sum(4); /*Still A*/
summer2.sum(8);/*Still A*/
console.log(summer2.sum()); /*Still A*/
var summer3 = returnObject(); /* Create scope B */
summer3.sum(2); /*B*/
summer3.sum(4); /*B*/
summer3.sum(8); /*B*/
console.log(summer3.sum()); /*B*/
var summer4 = returnObject(); /* Create scope C */
summer4.sum(2); /*C*/
summer4.sum(4); /*C*/
summer4.sum(8); /*C*/
console.log(summer4.sum()); /*C*/
答案 2 :(得分:1)
在这两种情况下,你都有一个函数在你调用它时返回一个对象。
使用returnImmediatelyExecutedFunction
运行一次函数(创建一个对象),然后对对象执行一系列不同的操作(这不是函数),包括从summer1
复制它到summer2
,returnImmediatelyExecutedFunction
。
使用returnObject
,您可以运行该函数两次,并为两个不同的对象执行一些不同的操作。