这种现象被称为: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。
这里是another example:
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);
这样全局变量就不会受到影响。
如您所见,无论您将变量声明放在何处,它始终提升到本地闭包的顶部。
旁注:
这也适用于函数。
考虑this piece of code:
test("Won't work!");
test = function(text) { alert(text); }
这会给你一个参考错误:
Uncaught ReferenceError: test is not defined
这让很多开发人员望而却步,因为 this piece of code 工作正常:
test("Works!");
function test(text) { alert(text); }
如上所述,原因是分配部分没有被提升。所以在第一个示例中,当test("Won't work!") 运行时,test 变量已经被声明,但还没有分配给它的函数。
在第二个例子中,我们没有使用变量赋值。相反,我们使用了正确的函数声明语法,确实完全提升了函数。
Ben Cherry 就此写了一篇出色的文章,标题恰如其分 JavaScript Scoping and Hoisting。
阅读。它将为您提供完整的详细信息。