Closure Conditional - 当它没有作为参数传递时,这个返回函数如何将值设置为参数?

时间:2013-03-20 14:35:25

标签: javascript closures

因此,return function (n)仍然返回最初作为扩充提供给其父函数的值。但是我不明白为什么,当我没有从var digit_name = (function(){传递n的值时,return function(n){从原始参数中得到它的值。

特别是因为我用var n = 4;

覆盖了它

JS

   var digit_name = (function(){
       var names;
       var n = 4;
       return function(n){
           if(!names){
               names = ['zero','one','two','three'];
           }
       return names[n];
       }
   }());
   console.info(digit_name(3)); //Three

如果我用return function(n)号码覆盖return function(1),我会SyntaxError: missing formal parameter。我知道返回名称[n]不会知道n是什么,为什么不给出n is undefined错误?

3 个答案:

答案 0 :(得分:2)

我不完全确定你在问什么,所以我只是要解释你为什么得到你的输出......

当代码运行时,执行IIFE(立即调用的函数表达式),digit_name引用从它返回的函数。该函数仍然可以通过闭包访问外部nnames变量。

然后调用digit_name并传递一个参数。 digit_name的形式参数是n,它隐藏了外部作用域中声明的n。您无法再以任何方式引用该n。因此,无论您传递给digit_name的任何价值都将被使用。

实际上,在这种情况下,IIFE是没有意义的(除了它可以防止您每次调用函数时都必须创建数组)并且除了该数组差异之外,您的代码等效于此:

var digit_name = function (n) {
    return ['zero','one','two','three'][n];
};
console.info(digit_name(3)); // "three"

答案 1 :(得分:1)

如果你在控制台中查看digit_name的定义,你会看到它是这个函数:

   function (n){
       if(!names){
           names = ['zero','one','two','three'];
       }
       return names[n];
   }

所以你没有覆盖n,因为这个函数中n的范围现在是参数n,而不是上面声明的变量。

答案 2 :(得分:1)

在您的示例中,您与变量n进行命名和范围冲突。外部函数中定义的var n的值为4.您的内部函数接受声明为n的单个参数。因此,内部函数中的n变量引用其内部作用域,并且不再引用外部函数中的var n。如果你想要一个默认值,你可以将外部变量命名为不同的东西,并检查内部函数中是否存在值n

var digit_name = (function () {
    var names;
    var defaultn = 0;
    return function (n) {
        if (!n) n = defaultn;
        if (!names) {
            names = ['zero', 'one', 'two', 'three'];
        }
        return names[n];
    }
}());
console.info(digit_name(3)); //Three
console.info(digit_name()); //zero