为什么我会得到" Uncaught ReferenceError"即使声明变量没有" var"关键词?

时间:2017-02-05 13:36:41

标签: javascript

我遇到了以下代码段:



(function() {
    bar = 5;
    var bar = 10;
    console.log("value of bar inside the self invoking function = " + bar);
})();
console.log("value of bar out of function scope " + bar);




当我执行上面的代码时,我得到:

  

"未捕获的ReferenceError"

用于第二个控制台

2 个答案:

答案 0 :(得分:6)

这是由于"变量提升"。在解析javascript时声明变量,因此在执行时,引擎已经知道范围内可用的所有变量,因此可以分配给它们。提升过程完成后,您的功能实际上就像这样。



(function() {
    var bar;
    bar = 5;
    bar = 10;
    console.log("value of bar inside the self invoking function = " + bar);
})();

console.log("value of bar out of function scope " + bar);




您可以在MDN上详细了解它:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var#var_hoisting

答案 1 :(得分:0)

var声明的所有变量都被提升到声明它们的函数的顶部。因此,如果变量在函数内定义,它将被移动到函数的顶部,如果它被定义在全局范围内,它将被移到全局上下文的顶部。

(function() {
    bar = 5;
    var bar = 10;
    console.log("value of bar inside the self invoking function = " + bar);
})();

在这种情况下,你已经在匿名函数中定义了变量,所以它将被移动到这个函数的顶部,并在提升之后就像是

(function() {
    var bar;
    bar = 5;
    bar = 10;
    //...rest of the code
})();

但是这个变量仅在该功能的本地范围中可用,它在全局范围内不可用。这就是为什么当您尝试在全局范围中访问它时Uncaught ReferenceError

这是一篇很好的文章,解释了JavaScript中的变量范围和变量提升。 http://javascriptissexy.com/javascript-variable-scope-and-hoisting-explained/

需要注意的是,只有使用var声明的变量才会被提升。如果您使用ES6 let关键字来声明变量,那么它将不会被提升。所以

(function() {
    bar = 5;
    let bar = 10;
    console.log("value of bar inside the self invoking function = " + bar);
})();

不会工作,你会得到同样的错误。您可以阅读更多相关信息here