4

在下面的代码片段中,我声明了一个全局变量,然后检查它是否存在于函数中。

<script>
x = 5;
$(function() {
   var x = x || 3;
   console.log(x); // prints 3
});
</script>

这表现不同:

<script>
x = 5;
$(function() {
   var y = x || 3;
   console.log(y); // prints 5
});
</script>

我希望在第一个示例中,内部作用域中的变量声明将检测到 x 已经存在于全局作用域中,并取其值。为什么第一个例子3?

具体来说,我最近编写了一些代码来检查var _gaq = _gaq || []jQuery 就绪范围,并且当没有任何内容发布到 Analytics 时感到困惑。

4

3 回答 3

3

x在错误的范围内寻找。由于变量提升,实际上在您的检查发生之前定义了一个值为 的var x局部变量:xundefinedx || 3

var x = x || 3;

实际上是:

var x = undefined;
x = x || 3;

只需将其更改为xwindow对象上查找:

var x = window.x || 3;
于 2012-07-16T19:41:35.510 回答
1

第一个示例记录 3 因为 any variable that is initialized inside a function using the var keyword will have a local scope. If a variable is initialized inside a function without var, it will have a global scope.

所以在第一种情况下,当局部x被分配时,由于它未初始化,它被分配 3。

而在第二种情况下,x指的是全局变量,因为函数内部x没有声明。x

相反,如果你尝试这个

<script>
x = 5;
$(function() {
   x = x || 3;
   console.log(x);
});
</script>

或者

<script>
x = 5;
$(function() {
   var x = window.x || 3;
   console.log(x);
});
</script>

你会得到预期的结果5

此外,与 C 及其家族(具有块级作用域)不同,JavaScript 具有函数级作用域。块,例如 if 语句,不会创建新范围。只有函数会创建新范围。

所以如果我要写类似的东西

#include <stdio.h>
int main() {
    int x = 1;
    printf("%d, ", x); // 1
    if (1) {
        int x = 2;
        printf("%d, ", x); // 2
    }
    printf("%d\n", x); // 1
}

输出:1,2,1

相比于

var x = 1;
console.log(x); // 1
if (true) {
    var x = 2;
    console.log(x); // 2
}
console.log(x); // 2

输出:1,2,2

阅读这篇关于JavaScript 作用域和提升的优秀博客文章,以更好地理解它。

于 2012-07-16T19:43:50.610 回答
0

var xin 函数声明 x 是函数的局部变量,因此 in xx || 3不是全局 x ,因此未定义,因为它尚未初始化。

var y = x || 3;x 中是全局 x,因为没有 x 局部函数。

于 2012-07-16T19:38:56.493 回答