首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么JS需要执行上下文?

为什么JS需要执行上下文?
EN

Stack Overflow用户
提问于 2019-07-20 09:36:29
回答 1查看 224关注 0票数 0

我是JS的新手,我正在学习JS中执行上下文的角色,并问自己在JS中执行上下文的好处是什么,以及为什么通过执行上下文运行JS。第二个问题是我们所知道的全局和功能性执行上下文,每个上下文有两个阶段,创建阶段和执行阶段。那么,为什么我们需要这两个阶段?拥有它们有什么意义。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-07-20 09:50:53

“执行上下文”的概念为在创建和执行全局环境或调用函数时提供了一种推理方式。它是局部变量(全局环境中的全局变量)、参数(函数)等的概念容器。只要JavaScript引擎按照规范定义的执行上下文行为来实现语言,就可以编写它实际上没有任何对象的“执行上下文”。

执行上下文帮助解释的一件事是闭包的行为。在给定执行上下文中创建的函数具有(概念上)对该上下文的引用,即使在与上下文相关的函数调用完成之后:

代码语言:javascript
复制
function foo(answer) {
    return function say() {
        console.log(answer);
    };
}
const s = foo(42);
s(); // 42

这是因为函数say引用了创建它的foo调用的上下文(更具体地说,它的“词法环境”)。在foo返回之后,这个词法环境仍然存在,因为某些东西仍然有引用(say)。因此,对say的调用在后来起作用了。

有两个阶段的原因是允许在声明之前使用标识符。这主要用于函数声明:

代码语言:javascript
复制
main();

function main() {
    console.log("Worked");
}

第一个阶段处理函数声明(和var语句),然后逐步运行代码。如果没有第一阶段,上面的代码将从main();开始失败,因为main将被未声明。当然,使用上面的简单示例,您可以将main();调用移到函数声明之后,但是更复杂的情况就更难用这种方式解决了。没有两个阶段(例如,早期C )的语言必须提供一种机制,用于“转发声明”稍后定义的内容。有两个阶段意味着JavaScript不必有这样的阶段。(公平地说,C与JavaScript的不同之处在于,它需要知道编译期间所有标识符都引用了什么,即使标识符在函数中的代码中也是如此。因此,它需要前向声明,以便允许foobar相互调用。在调用函数之前,JavaScript不会检查函数中使用的标识符,所以即使没有两个阶段,C中使用前向声明的原因在JavaScript中也不会出现。)

但并不是完全成功。让var语句在代码中到达var语句之前初始化它们用undefined声明的变量,这通常是bug和混乱的根源:

代码语言:javascript
复制
console.log(answer); // undefined
var answer = 42;

人们很容易被这样一个事实所迷惑:一半的var answer = 42;是提前完成的( var answer部分),而另一半(answer = 42;)是在稍后到达语句时才完成的。

这就是为什么letconst在第一阶段创建但不初始化它们的变量的原因。可以在声明变量的上面使用变量,但只能在初始化后运行的代码中使用:

代码语言:javascript
复制
function foo() {
    console.log(answer);
}
// foo(); <== Would fail, `answer` isn't initialized yet
let answer = 42;
foo(); // Works, logs 42
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57123463

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档