Javascript执行上下文和变量可访问性

Javascript执行上下文和变量可访问性,javascript,Javascript,现在我知道局部作用域变量在该函数之外的任何地方都不可用,但我在这里混淆的是执行堆栈。因此,当调用foo时,堆栈将是全局的,foo,bar。变量查找也会在堆栈中向下移动。因此,按照这种逻辑,当从foo中调用时,为什么不能在bar中访问“a”。每个函数只能访问它们自己的堆栈帧,而不能访问它的调用方 此外,此堆栈由内部/运行时/编译器在内部处理,高级语言无法直接访问,高级语言通过使用符号变量访问其数据,而符号变量的后台数据可以来自各种位置。变量的可见性由语言定义,与它们在内存中的存储位置没有直接关系

现在我知道局部作用域变量在该函数之外的任何地方都不可用,但我在这里混淆的是执行堆栈。因此,当调用foo时,堆栈将是全局的,foo,bar。变量查找也会在堆栈中向下移动。因此,按照这种逻辑,当从foo中调用时,为什么不能在bar中访问“a”。

每个函数只能访问它们自己的堆栈帧,而不能访问它的调用方

此外,此堆栈由内部/运行时/编译器在内部处理,高级语言无法直接访问,高级语言通过使用符号变量访问其数据,而符号变量的后台数据可以来自各种位置。变量的可见性由语言定义,与它们在内存中的存储位置没有直接关系

这在几乎所有语言中都是一样的


在JavaScript中,函数确实可以访问封闭范围。如果需要,作用域也可以“堆叠”(我认为正确的术语是它们“嵌套”),但这与调用堆栈不同。

“变量查找也会向下移动堆栈”否,变量查找不考虑调用堆栈。涉及作用域时,不考虑整个堆栈。执行堆栈与作用域关系不大。作用域更像一棵树,这里的
foo
bar
是同级,都是全局作用域的子级。当
bar
查找
a
时,它从自己的作用域开始,然后遍历每个父作用域,直到找到
a
或在全局作用域中找不到它。它从不检查
foo
a
,因为
foo
不是bar的祖先,而是兄弟。它们是同级的,因为作用域树与函数的声明位置有关,而与函数的调用方式无关,这也是执行堆栈的关系。
foo
bar
都在同一个作用域中声明,因此它们都成为该作用域的子级。
function foo(){
 var a = 'test';
 bar();
}

function bar(){
 alert(a);
}

foo();