变量:本地范围、全局范围还是 JavaScript 引擎?

Posted

技术标签:

【中文标题】变量:本地范围、全局范围还是 JavaScript 引擎?【英文标题】:Variable: local scope, global scope or is it the JavaScript engine? 【发布时间】:2013-11-06 16:34:01 【问题描述】:

这是我在学习 javascript 范围时发现的一些有趣的东西。

代码

var foo = "This is a global variable.";

var bar = function() 
    alert(foo);
    foo = "Value has been modified";


bar();
alert(foo);

这给出了你认为你会得到的正常响应,但如果我改变这一行:

来自:

foo = "Value has been modified";

收件人:

var foo = "Value has been modified";

我得到 foo 的 undefined 值,这是为什么呢?既然函数是全局作用域,怎么不接受前面的var关键字?

编辑

现在我基本上明白了发生了什么,功能栏中的var foo 将获得最重要的因为 var 关键字并被提升,但它会被提升没有值它已被分配。

【问题讨论】:

两个字:variable hoisting "我得到一个未定义的 foo 值,这是为什么呢?" -- 不,你不知道jsfiddle.net/up8bX 移动变量栏并不能解决这个问题。 Understanding Global & Local Scope in Javascript 的可能副本 阅读 ECMA-262 关于entering an execution context 的内容可能会有所帮助,尤其是declaration binding instantiation。 【参考方案1】:

var 声明中,它有两个部分 - 实际声明:

var foo //;

... 和分配,这是可选的:

= 1234567890;

如果没有对其进行赋值,则变量(如果尚未定义)默认为undefined


变量声明部分被移动到当前作用域的顶部(函数的开头),但不是实际的赋值(所以它相当于下面的):

var foo = "This is a global variable.";

var bar = function() 
    var foo; // undefined
    alert(foo); // yes, it's undefined
    foo = "Value has been modified"; // modify local, not global


bar();
alert(foo); // the global one

函数创建自己的作用域——例如:

var test = function ()
   var bar = 1;
    console.log(bar); // 1
;
test();
console.log(bar); // ReferenceError: bar is not defined

【讨论】:

但是如果它们被提升到当前作用域的顶部,为什么它不显示它被分配的值? @htmltroll: 因为实际赋值没有被提升,只有定义。 当您说修改本地而不是全局时,您是什么意思? foo 不会修改全局起始变量 foo 吗?因为函数在全局范围内。 我不喜欢“提升”这个词。它推断整个语句“移动到范围的顶部”(即执行上下文)。 ECMA-262 说的是首先处理变量声明,然后评估语句和表达式。因此,即使使用了initialiser,声明的变量在被赋值之前就已经存在。 @htmltroll:函数的内容在另一个范围内 - "Value has been modified" 仅在函数内部更改 foo【参考方案2】:

通过使用var,您是在告诉引擎使用名为 foo 的 本地 变量,隐藏全局变量。

您在alert 上未定义的原因是使用var 会影响整个范围,而不仅仅是从那时起。你可以这样写:

var foo;
alert(foo);
foo = "Value has been modified";

【讨论】:

【参考方案3】:

JavaScript 引擎将解析您的代码并将 var 声明移动到其范围的顶部,但您对其的字符串分配将保持在原来的位置。解析后,以下是您的代码的解释方式:

var foo = "This is a global variable.";    

var bar = function() 
    var foo;
    alert(foo);
    foo = "Value has been modified";
    

bar();
alert(foo);

由于它在函数顶部创建了一个没有任何值的局部变量,因此您的警报将显示undefined

【讨论】:

以上是关于变量:本地范围、全局范围还是 JavaScript 引擎?的主要内容,如果未能解决你的问题,请参考以下文章

了解 Javascript 中的全局和本地范围

Python 变量范围

在 C# Web 浏览器中创建 javascript 变量全局范围

JS 变量的作用域

了解 Javascript 中的全局和局部范围

检查变量是不是设置在全局范围内?