这是研究 JavaScript 内部工作方式的系列文章的第一篇. 我会尽力使它变得有趣, 并且不让你感到厌烦, 因为我知道这些东西有时会变得非常乏味!
想象一下, 飞行员知道是飞机怎样飞行的, 而我们每天运行 JavaScript 代码, 但知道它是如何运行吗?
谈谈 JavaScript 执行线程
先让我们敲出一些简单的 JavaScript 代码:
- const num = 3;
- function addOne(x) {
- const result = x + 1;
- return result;
- }
- const output = addOne(num);
上面的代码没什么让你值得兴奋的, 但是可以很好地帮助我们演示执行线程.
当执行 JavaScript 时, 代码会逐行 (单线程) 执行, 因此在我们的代码中, 要被执行的第一行是:
const num = 3;
下一个问题是, 执行这行代码会发生什么? num 存储在哪里?
num 存储在全局内存 / 执行上下文中, 看起来像这样:
然后进入下一行:
function addOne(x) {
请务必注意, 我们在这里声明了一个函数, 但是还不执行. 因此, 我们将函数名称与整个函数的值一起存储.
上面的 - f - 是整个函数的简写.
现在转到下一行, 有人可能认为下一行是函数的主体, 但是由于我们仅声明函数而不是运行它, 因此要运行的下一行是:
const 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(执行上下文), 将来我们将会更深入地研究它们.
来源: http://www.css88.com/web/javascript/17000.html