JavaScript范围:全局变量混淆

时间:2017-05-19 15:21:08

标签: javascript scope

我无法理解为什么以下代码打印1而不是10.我认为console.log会打印10,因为如果变量未在函数中声明,则它是全局范围的一部分。

如果删除该行function a(){},则console.log语句将打印10.有人可以解释为什么此行的存在会影响a的值。

此外,如果这个问题可以改进,我将不胜感激任何建议

function b() { 
    a = 10; 
    return;
    function a(){}
} 
var a = 1; 
b(); 

console.log(a);

3 个答案:

答案 0 :(得分:0)

只需将console.log(a);添加到您的函数中,您就会发现'a'是一个具有局部范围的函数,这意味着它在函数b()中,并且无法从外部实际调用。因此,a的值保持为1,因为没有真正影响它。

function b() { 
    console.log(a);
    a = 10; 
    return;
    function a(){}
} 
var a = 1; 
b(); 

console.log(a);

答案 1 :(得分:0)

函数声明创建局部变量,并且所有声明的变量都提升到其包含的函数范围的顶部。因此,你有相当于:

的东西
function b() { 
    function a(){}
    a = 10; 
    return;
} 

又大致相当于

function b() { 
    var a = function(){}
    a = 10; 
    return;
} 

正如您在此表单中看到的那样,a显然是一个局部变量,因此a = 10为本地a分配值,而不是全局a

答案 2 :(得分:0)

因为函数声明和变量在引擎盖下都被类似地处理。

调用函数时,首先解析其内容以配置堆栈帧为其执行做好准备。

作为此过程的一部分,函数声明和变量作为标识符/值对插入到调用函数时创建的堆栈帧(执行上下文)内的相同数据结构(词法环境中的环境记录)中。

因此,通过在a内声明函数b,您可以在为b调用而创建的环境记录中创建一个名为“a”的标识符,并隐藏a外在的背景。

外部上下文中的a仍为1