1)为什么JavaScript中会有这种不一致-我原以为第四行也会返回11:
(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) == NaN2)我正在把一种语言的编译器写成javascript。我使用var来避免临时变量污染全局空间。就在上面发生的时候,我的临时变量是n,覆盖也没问题。
有没有其他方法让我可以(重新)定义n,这样如果之前没有定义n,它仍然认为n是局部的?
下面的两个变体用tmp污染了名称空间,我想避免这样的情况:
(function(n, m) { tmp = n + m; return tmp })(3, 8) == 11
(function(n) { return function(m) { tmp = n + m; return tmp } })(3)(8) == 11发布于 2017-12-23 05:47:42
在您的第四个示例中:
(function(n) { return function(m) { var n = n + m; return n } })(3)(8) // == NaN...您已经用一个局部声明隐藏了外部函数的n参数。由于您没有为该局部变量指定任何初始值设定项,因此其缺省值为undefined。undefined加上任何数字都是NaN。
您可能想知道为什么这与您的第二个示例不同:
(function(n, m) { var n = n + m; return n })(3, 8) // == 11答案是作用域。在第二个示例中,var n出现在n参数已经存在的作用域中,因此不会隐藏它(使用与同一作用域中的参数具有相同标识符的var是不可行的)。但在第四个示例中,var n出现在参数n所在的作用域的嵌套作用域中。因此它隐藏了父n。
在这里,var什么也不做,因为已经有了一个作用域内的n:
function foo(n) {
var n;
console.log(n);
}
foo(42); // 42
但在这里,它做到了:
function foo(n) {
(function() {
var n;
console.log(n);
})();
}
foo(42); // undefined
...because参数和var位于不同的作用域。
下面的两个变种用tmp污染了名称空间,我想避免这种情况
不需要tmp (尽管本地tmp就可以了)。如果你想要一个嵌套函数,那就不要在n上使用var
console.log(
(function(n) { return function(m) { n = n + m; return n } })(3)(8) // == NaN
);
也就是说,本地 tmp (使用var)不是坏事:
console.log(
(function(n) { return function(m) {
var tmp = n + m;
return tmp;
}})(3)(8) // == 11
);
...but你必须声明它。如果var没有声明它,代码就会成为*的牺牲品,这是您确实想要避免的。:-)
*(这是我贫乏的小博客上的一篇文章)
发布于 2017-12-23 05:55:52
通过在内部函数中将var放在n之前,您将声明一个新的n变量,此时该变量为undefined,这也是您获得NaN的原因(例如,undefined +8= NaN)。
不需要声明新的变量。只需返回值:
(function(n) {
return function(m) {
return n + m;
}
})(3)(8)https://stackoverflow.com/questions/47947692
复制相似问题