为了理解这一点,我认为使用更简单的示例很有帮助。看看下面两个memoized函数。唯一的区别是成功记忆代码后()
后add : function(){ ... }()
。
var failed_memoization = {
add : function(){
var counter;
return function(number){
if(counter){
counter = counter + number;
return counter;
}
counter = number;
return counter;
} //NOTE: NO function call brackets here
}
}
var successful_memoization = {
add : function(){
var counter;
return function(number){
if(counter){
counter = counter + number;
return counter;
}
counter = number;
return counter;
}
}() //NOTE: the function call brackets here!!
};
}
现在让我们执行这两个函数。
console.log('Failed Memoization');
console.log(failed_memoization.add(5)); //We wanted 5, but this prints the text of the function instead.... Okay, lets try something else
console.log(failed_memoization.add()(5)); //5
console.log(failed_memoization.add()(10)); //10 (Wanted it to be 5+10 = 15.
console.log('successful_memoization');
console.log(successful_memoization.add(8)); //8
console.log(successful_memoization.add(16)); //24 (This is what we wanted 8 + 16 = 24)
那么,什么是怎么回事是,successful_memoization
当我们把()
其add : function(){...}()
结束。同样,这个函数在创建静态对象时立即执行。反过来,执行该函数返回对象function (number){...}
,其结果在于:add : function (number){...}
不是add : function(){}
它最初出现。
什么还重要的是要注意的是,var counter
声明外return function(name){}
。由于它仍在add : function(number){...}
内使用,因此可以在该函数中访问此变量。对于failed_memoization.add()(number)
,我们每次执行该函数时都会使用新的counter
,因为我们执行第一个函数,然后执行每个调用的内部函数。对于successful_memoization.add(number)
,我们在初始化时执行了外部函数,因此counter
将在所有后续调用中保留,并且不会被覆盖。
值得注意的是,即使在outter函数返回后,内函数访问变量函数的技巧也被称为'closure' – 7hi4g0 2013-11-07 17:43:24
这是书中的Javascript - 好的部分,还有更好的部分那里的过程描述。 – 2015-12-08 11:29:58