JavaScript 执行线程图解
疯狂的技术宅 前端先锋
翻译:疯狂的技术宅
作者:Paul Ryan
来源:alligator.io
正文共:2337 字
预计阅读时间:7 分钟
这是研究 JavaScript 内部工作方式的系列文章的第一篇。我会尽力使它变得有趣,并且不让你感到厌烦,因为我知道这些东西有时会变得非常乏味!
想象一下,飞行员知道是飞机怎样飞行的,而我们每天运行 JavaScript 代码,但知道它是如何运行吗?
谈谈 JavaScript 执行线程
先让我们敲出一些简单的 JavaScript 代码:
1const num = 3;
2
3function addOne(x) {
4 const result = x + 1;
5 return result;
6}
7
8const output = addOne(num);
上面的代码没什么让你值得兴奋的,但是可以很好地帮助我们演示执行线程。
当执行 JavaScript 时,代码会逐行(单线程)执行,因此在我们的代码中,要被执行的第一行是:
1const num = 3;
下一个问题是,执行这行代码会发生什么?num 存储在哪里?
num 存储在全局内存/执行上下文中,看起来像这样:
显示如何执行第一行的动画
然后进入下一行:
1function addOne(x) {
请务必注意,我们在这里声明了一个函数,但是还不执行。因此,我们将函数名称与整个函数的值一起存储。
第二行如何执行
上面的 - f - 是整个函数的简写。
现在转到下一行,有人可能认为下一行是函数的主体,但是由于我们仅声明函数而不是运行它,因此要运行的下一行是:
1const output = addOne(num);
与上面类似,我们将标签 output 发送到内存,但还没有值,因为我们必须运行函数。
保存函数标签
有趣的来了!接下来执行 addOne 函数。
当一个函数被执行时,它被添加到 call stack(调用栈)中。调用堆栈的底部总是有 global/main ,我们现在将 addOne(3) 入栈。
调用堆栈
我们还为该函数创建一个 execution context (执行上下文)。函数中声明的任何变量都会被添加到函数的执行上下文中。
将要添加的第一个变量是函数的参数,在本例中为 x。
添加函数参数
现在,我们移至下一行并将 result 存储在 execution context 中。
存储结果
在下一行,用了 return 关键字来标记函数的结束。我们从调用栈中弹出 addOne(),并给 output 赋值为4。
所以首先从 call stack 中弹出 addOne。
从调用栈弹出
现在是最后一步,将值 4 分配给 output 变量。
最后一步
完成!
就是这些了!我希望这能够演示 JavaScript 代码是如何逐步执行的。在本文中提到了 call stack (调用栈)和 execution context(执行上下文),将来我们将会更深入地研究它们。
原文链接
https://alligator.io/js/thread-of-execution/