这种现象称为:JavaScript变量提升。
您绝对不会在函数中访问全局变量。您只访问局部value
变量。
您的代码等效于以下内容:
var value = 10;
function test() {
var value;
console.log(value);
value = 20;
console.log(value);
}
test();
还感到惊讶undefined
吗?
说明:
每个JavaScript程序员迟早都会碰到这一点。简单地说,任何变量声明总是悬挂到本地盖顶部。因此,即使您在第一次console.log
调用后声明了变量,也仍然会认为它是在此之前声明的。
但是,只有声明部分被吊起;另一方面,分配不是。
因此,当您第一次调用时console.log(value)
,您引用的是本地声明的变量,该变量尚未分配任何内容。因此undefined
。
这是另一个例子:
var test = 'start';
function end() {
test = 'end';
var test = 'local';
}
end();
alert(test);
您认为这会引起什么警报?不,不要只是继续阅读,请考虑一下。有什么价值test
?
如果您说的不是start
,则您错了。上面的代码等效于此:
var test = 'start';
function end() {
var test;
test = 'end';
test = 'local';
}
end();
alert(test);
这样全局变量就不会受到影响。
正如你所看到的,无论在哪里你把你的变量声明中,它始终是悬挂到本地盖顶部。
边注:
这也适用于功能。
考虑这段代码:
test("Won't work!");
test = function(text) { alert(text); }
这将为您提供参考错误:
未捕获的ReferenceError:未定义测试
因为这段代码可以正常工作,所以这使很多开发人员不满意:
test("Works!");
function test(text) { alert(text); }
如上所述,这样做的原因是未悬挂分配部件。因此,在第一个示例中,当test("Won't work!")
运行时,test
变量已被声明,但尚未分配功能。
在第二个示例中,我们不使用变量赋值。相反,我们使用了正确的函数声明语法,这确实使函数完全提升了。
Ben Cherry在这方面写了一篇很棒的文章,标题为JavaScript Scoping and Hoisting。
阅读。它会为您提供整个细节的详细信息。