首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Javascript闭包:变量的不一致重用

Javascript闭包:变量的不一致重用
EN

Stack Overflow用户
提问于 2017-12-23 05:40:44
回答 2查看 76关注 0票数 1

1)为什么JavaScript中会有这种不一致-我原以为第四行也会返回11:

代码语言:javascript
复制
(function(n, m) { n = n + m; return n })(3, 8)                         == 11
(function(n, m) { var n = n + m; return n })(3, 8)                     == 11

(function(n) { return function(m) { n = n + m; return n } })(3)(8)     == 11
(function(n) { return function(m) { var n = n + m; return n } })(3)(8) == NaN

2)我正在把一种语言的编译器写成javascript。我使用var来避免临时变量污染全局空间。就在上面发生的时候,我的临时变量是n,覆盖也没问题。

有没有其他方法让我可以(重新)定义n,这样如果之前没有定义n,它仍然认为n是局部的?

下面的两个变体用tmp污染了名称空间,我想避免这样的情况:

代码语言:javascript
复制
(function(n, m) { tmp = n + m; return tmp })(3, 8)                     == 11
(function(n) { return function(m) { tmp = n + m; return tmp } })(3)(8) == 11
EN

回答 2

Stack Overflow用户

发布于 2017-12-23 05:47:42

在您的第四个示例中:

代码语言:javascript
复制
(function(n) { return function(m) { var n = n + m; return n } })(3)(8) // == NaN

...您已经用一个局部声明隐藏了外部函数的n参数。由于您没有为该局部变量指定任何初始值设定项,因此其缺省值为undefinedundefined加上任何数字都是NaN

您可能想知道为什么这与您的第二个示例不同:

代码语言:javascript
复制
(function(n, m) { var n = n + m; return n })(3, 8) // == 11

答案是作用域。在第二个示例中,var n出现在n参数已经存在的作用域中,因此不会隐藏它(使用与同一作用域中的参数具有相同标识符的var是不可行的)。但在第四个示例中,var n出现在参数n所在的作用域的嵌套作用域中。因此它隐藏了父n

在这里,var什么也不做,因为已经有了一个作用域内的n

代码语言:javascript
复制
function foo(n) {
    var n;
    console.log(n);
}
foo(42); // 42

但在这里,它做到了:

代码语言:javascript
复制
function foo(n) {
    (function() {
        var n;
        console.log(n);
    })();
}
foo(42); // undefined

...because参数和var位于不同的作用域。

下面的两个变种用tmp污染了名称空间,我想避免这种情况

不需要tmp (尽管本地tmp就可以了)。如果你想要一个嵌套函数,那就不要在n上使用var

代码语言:javascript
复制
console.log(
    (function(n) { return function(m) { n = n + m; return n } })(3)(8) // == NaN
);

也就是说,本地 tmp (使用var)不是坏事:

代码语言:javascript
复制
console.log(
    (function(n) { return function(m) {
        var tmp = n + m;
        return tmp;
    }})(3)(8) // == 11
);

...but你必须声明它。如果var没有声明它,代码就会成为*的牺牲品,这是您确实想要避免的。:-)

*(这是我贫乏的小博客上的一篇文章)

票数 10
EN

Stack Overflow用户

发布于 2017-12-23 05:55:52

通过在内部函数中将var放在n之前,您将声明一个新的n变量,此时该变量为undefined,这也是您获得NaN的原因(例如,undefined +8= NaN)。

不需要声明新的变量。只需返回值:

代码语言:javascript
复制
(function(n) {
  return function(m) {
    return n + m;
  }
})(3)(8)
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47947692

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档