阅读一本书的示例,有人可以解释函数调用fibonacci时如何在函数本身没有声明任何参数的情况下对参数“ i”征用?
var fibonacci = (function () {
var memo = [0, 1];
var fib = function (n) {
var result = memo[n];
if (typeof result !== 'number') {
result = fib(n - 1) + fib(n - 2);
memo[n] = result;
}
return result;
};
return fib;
}());
for(var i = 0; i <= 10; i += 1) {
document.writeln('// ' + i + ': ' + fibonacci(i));
}
(function(){}());
中,它在其中返回
fib
函数,该函数需要参数。
var fib = function(n){}
...
return fib;
var fibonacci = (function () { // Self-executing anonymous function
var memo = [0, 1]; // local variable within anonymous function
var fib = function (n) { // actual fib function (takes one argument)
var result = memo[n]; // fib function is now bound to the memo variable from the outer scope and a closure is formed
if (typeof result !== 'number') {
result = fib(n - 1) + fib(n - 2);
memo[n] = result;
}
return result;
};
return fib; // return fib (fibonacci is now set to the function fib defined above, which takes one argument)
}());
这个系统(从自我执行的匿名函数中返回函数)允许您在本地范围中定义变量,该变量仍然可以由返回的函数使用,但不能通过范围之外的函数来使用。这是一个example。
在JavaScript中,该技术称为closure
。在
MDN指南中阅读有关它的更多信息。the功能返回函数does
要理解这一点,我认为使用一个更简单的示例很有帮助。看看下面的两个回忆功能。唯一的区别是成功的记忆代码之后。
()
现在让我们执行这两个功能。
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)
wich wich会导致分配:
successful_memoization
()
not当它出现时。还要注意的是,
add : function(){...}()
被声明为
。由于它仍在
function (number){...}
中使用,因此该变量在该功能中可访问。对于
add : function (number){...}
,它每次执行该函数时都会使用新的
add : function(){}
,因为我们执行第一个函数,然后在每个呼叫上执行内部函数。因为var counter
我们在初始化时执行了外部函数,因此
return function(name){}
将在所有后续的呼叫中持续存在,并且不会被覆盖。
add : function(number){...}
这是一个自我执行的函数。
IT声明一个函数表达式,该函数表达式返回函数(
failed_memoization.add()(number)
),立即执行外部函数表达式(
counter
),并将其返回值(为
successful_memoization.add(number)
)分配给
counter
变量。有一个自称函数,它将用标识符返回该函数
var fibonacci = (function() {
...
return fib;
})();
fib
。这样,您可以创建一个私有变量
()
,该变量只能通过函数访问。所以
fib
实际上是
fibonacci
。
函数确实有一个论点。请注意,从第一行开始的未命名函数不是最终称为
fib
的函数。由于您关闭支架后立即有
fibonacci
立即,因此立即调用了该不愿透露姓名的功能。这个未命名的函数返回var fibonacci
,这是一个局部变量,分配了单一词汇函数。因此,
function(n){...}
最终指的是未命名函数返回的函数,即:
fibonacci
是:
fibonacci
注意,此功能是指未命名函数的局部变量,以进行记忆。要注意的至关重要的事情是立即称之为未命名函数,以下是一些说明此技术的示例:
}
具有返回1.的函数。
fib
但是,可变fibonacci
持有值1.