1

因此,return function (n)仍然返回最初作为增补赋予其父函数的值。但是我不明白为什么,当我没有传递 n 的值时,var digit_name = (function(){确实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。我知道 return names[n] 不会知道什么n,那么为什么不给出n is undefined错误呢?

4

3 回答 3

2

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

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

然后你调用digit_name并传递一个参数。digit_nameis的形式参数n,它隐藏n在外部范围中的声明。不再有任何方法可以引用该 external n。所以你传入的任何值digit_name都会被使用。

实际上,在这种情况下,IIFE 毫无意义(除了它可以防止您在每次调用函数时都必须创建数组),并且您的代码与此等价,除了数组差异:

var digit_name = function (n) {
    return ['zero','one','two','three'][n];
};
console.info(digit_name(3)); // "three"
于 2013-03-20T14:43:07.493 回答
1

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

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

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

于 2013-03-20T14:41:23.410 回答
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
于 2013-03-20T14:41:38.873 回答