Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/380.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript回忆录解释?_Javascript - Fatal编程技术网

Javascript回忆录解释?

Javascript回忆录解释?,javascript,Javascript,阅读一本书中的一个例子,有人能解释一下当函数本身没有声明任何参数时,对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) +

阅读一本书中的一个例子,有人能解释一下当函数本身没有声明任何参数时,对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));
}
var fibonacci=(函数(){
var memo=[0,1];
var fib=函数(n){
var结果=备忘录[n];
如果(结果类型!=='number'){
结果=fib(n-1)+fib(n-2);
备注[n]=结果;
}
返回结果;
};
返回fib;
}());
对于(var i=0;i
这是一个自动执行的函数


它声明一个函数表达式,该表达式返回一个函数(
fib
),立即执行外部函数表达式(
()
),并分配其返回值(即
fib
)到
fibonacci
变量。

函数
fibonacci
只接受一个参数。请注意,从第一行开始的未命名函数不是最终被称为
fibonacci
的函数。由于有
()
关闭大括号后立即
}
。此未命名函数返回一个局部变量
fib
,该局部变量分配了一个单参数函数。因此,
fibonacci
最终引用未命名函数返回的函数,即
fibonacci
如下:

var fib = function (n) {
    var result = memo[n];
    if (typeof result !== 'number') {
        result = fib(n - 1) + fib(n - 2);
        memo[n] = result;
    }
    return result;
};
请注意,为了便于记忆,此函数引用未命名函数的局部变量

需要注意的关键是
()
,它会立即调用未命名函数,下面是一些示例来说明此技术:

var a = (function() { return 1; });
变量
a
包含一个返回1的函数

var a = (function() { return 1; }());

然而,在这里,变量
a
保持值1。

因为函数返回的函数不带参数。

您正在创建一个自动执行的匿名函数
(function(){}());
它在其中返回
fib
函数,该函数带有一个参数。
var fib=function(n){}
返回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];
        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)
}());
此系统(从自执行匿名函数返回函数)允许您在局部作用域中定义变量,该变量仍可由返回的函数使用,但不能由作用域之外的函数使用


此技术在JavaScript中称为
closure
。请在上阅读更多有关此技术的信息。有一个自调用函数,它返回带有标识符
fib
的函数,然后将该标识符赋给标识符
fibonacci
。这样,您可以创建一个只有t才能访问的私有变量
memo
函数。因此
var fibonacci
实际上是
function(n){…}
为了理解这一点,我认为使用一个更简单的例子是很有帮助的。看看下面的两个记忆函数。唯一的区别是
后的
()
在成功的记忆代码上添加: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)
所以这里要做的是,为了
成功的记忆化
,当我们把
()
放在它的
add:function(){…}()
的末尾时。同样地,这个函数在创建静态对象时立即执行。反过来,执行该函数返回对象
function(number){…}
这将导致赋值:
add:function(number){…}
不是最初出现的
add:function(){}


还需要注意的是,
var计数器
return function(name){}
外部声明为。由于它仍在
add:function(number){…}
中使用,因此该变量可在该函数中访问。对于
失败的记忆。add()(number)
,每次执行该函数时,它都会使用一个新的
计数器,因为我们在每次调用时先执行第一个函数,然后执行内部函数。对于
成功的记忆。添加(数字)
我们在初始化时执行了外部函数,因此
计数器将在所有后续调用中保持不变,并且不会被覆盖。

值得注意的是,内部函数即使在outter函数返回后也访问outter函数上的变量的技术称为
闭包这本书是Javascript的好部分,对过程有更好的描述。
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)