繁体   English   中英

Javascript 执行上下文的说明

[英]Clarification on Javascript Execution Context

我一直在努力巩固我对 JS 执行上下文的理解,但我无法解释为什么下面的代码没有打印出“hello world”。

var foo = "foo";

function test1() {
    console.log(foo)
    var bar = "hello world";
    test2();
}

function test2() {
    console.log(bar);
}

test1();

我的(不可否认的是非常不稳定)理解test2()test1()内部执行,可以访问test1()的执行上下文,并且应该能够通过将作用域链向上移动到test1()来解析变量名称bar test1()的执行上下文,其中定义了bar 相反,我在尝试打印bar时收到参考错误。

由于 JS 的词法范围,我可以理解下面的代码是如何工作的,但我希望能解释一下 JS 如何在执行上下文和作用域链方面以不同的方式解释每个代码。

function test1() {
    console.log(foo)
    var bar = "hello world";
    function test2() {
        console.log(bar);
    }
    test2();
}

test1();

到目前为止,我自己寻找解释的最佳尝试是像这样修改第一个代码块:

var foo = "foo";
var bar = "not hello world :("

function test1() {
    console.log(foo)
    var bar = "hello world";
    test2();
}

function test2() {
    console.log(bar);
}

test1();

在这里,对test2()的调用打印出在全局作用域中定义的“not hello world :(”。我的第一个想法是test2()沿着作用域链向上到达test1的执行上下文,到达全局执行上下文,但这似乎不正确,因为它会在到达全局定义之前在test1()内部找到bar的定义。因此,我的第二个猜测是test2()的定义正在创建一个类似于“闭包”的捕获全局执行上下文的定义,并在test1()调用它会为bar的 null/undefined 生成一个值,因为这是它在函数定义时的值(根本没有要提升的声明)。因此,它不会向上移动到test1()的执行上下文以搜索标识符。

任何解释/资源都会非常有帮助。 我显然对这门语言很陌生,所以如果我的词汇/术语不太正确,我深表歉意。 在此先感谢您的帮助。

从哪里调用它以及调用者的范围并不重要。 解析局部变量重要的是它在哪里声明。

test2()无法访问bar因为在声明函数时,该作用域中没有名为bar变量。 事后无法操作该本地范围。 它是一成不变的。

这意味着函数可以访问局部作用域中的变量,或包含该函数声明的任何作用域中的变量。 这意味着遵循包含该函数声明的大括号{}一直回到文件的根目录。 把它想象成一棵树:你的函数可以访问该函数和树根之间的任何变量。 它将无法访问该树的其他分支。


这是一件非常好的事情。 它强制执行良好的封装。 从调用者的角度来看,您希望您的函数成为一个黑匣子。 您希望函数中的局部变量是真正的局部变量。 并且您想知道在编写函数时函数可以访问哪些变量,而不是在运行函数时对弹出的值感到惊讶。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM