JavaScript 的工作原理🔥🤖 [视觉解释]
JavaScript 是世界上最受喜爱和最受厌恶的语言之一。它之所以受喜爱,是因为它功能强大。你只需学习 JavaScript,无需其他任何知识,就能开发出一个全栈应用程序。它之所以受厌恶,也是因为它的行为方式出乎意料,令人不安,如果你不花心思去理解这门语言,你可能会讨厌它💔。
这篇博客将讲解 JavaScript 如何在浏览器中执行代码,我们将通过动图来学习 😆。读完这篇博客,你离成为 Rockstar 开发者又近了一步 🎸😎
执行上下文
“ JavaScript 中的一切都发生在执行上下文中。”
我希望每个人都记住这句话,因为它至关重要。你可以假设这个执行上下文是一个大容器,当浏览器想要运行一些 JavaScript 代码时就会被调用。
在这个容器里,有两个组件:1.内存组件 2.代码组件
内存组件又称为变量环境。在这个内存组件中,变量和函数以键值对的形式存储。
代码组件是容器中一次执行一行代码的地方。这个代码组件还有一个很酷的名字,叫做“执行线程”。我觉得这名字很酷!
JavaScript 是一种同步、单线程语言。这是因为它一次只能按照特定顺序执行一个命令。
代码执行
让我们举一个简单的例子,
var a = 2;
var b = 4;
var sum = a + b;
console.log(sum);
在这个简单的例子中,我们初始化两个变量 a 和 b,并分别存储 2 和 4。
然后我们将a和b的值相加并将其存储在sum变量中。
让我们看看 JavaScript 如何在浏览器中执行代码🤖
浏览器创建一个全局执行上下文,它由两个组件组成,分别是内存和代码组件。
浏览器将分两阶段执行 JavaScript 代码
1> 内存创建阶段
2> 代码执行阶段
在内存创建阶段,JavaScript 将扫描所有代码,并为代码中的所有变量和函数分配内存。对于变量,JavaScript 将在内存创建阶段存储 undefined;对于函数,它将保留整个函数代码,我们将在下面的示例中看到这一点。
现在,在第二阶段,即代码执行中,它开始逐行执行整个代码。
当它遇到var a = 2 时,它会将内存中的 2 赋值给 a 。在此之前, a 的值是未定义的。
类似地,它对变量 b 执行相同的操作。它将 4 赋给变量 b。然后计算并将总和的值存储在内存中,结果为 6。现在,在最后一步,它将总和的值打印到控制台中,然后在代码执行完成后销毁全局执行上下文。
如何在执行上下文中调用函数?
与其他编程语言相比,JavaScript 中的函数的工作方式有所不同。
让我们举一个简单的例子,
var n = 2;
function square(num) {
var ans = num * num;
return ans;
}
var square2 = square(n);
var square4 = square(4);
上面的例子有一个函数,它接受一个数字类型的参数并返回该数字的平方。
当我们运行代码时,JavaScript 会创建一个全局执行上下文,并在第一阶段为所有变量和函数分配内存,如下所示。
对于函数,它会将整个函数存储在内存中。
令人兴奋的部分来了,当 JavaScript 运行函数时,它将在全局执行上下文中创建一个执行上下文。
当遇到 var a = 2 时,它会将内存中的 n 赋值为 2。第 2 行是一个函数,由于该函数在内存执行阶段已经分配了内存,所以它会直接跳转到第 6 行。
square2 变量将调用 square 函数,并且 javascript 将创建一个新的执行上下文。
这个新的 square 函数执行上下文将在内存创建阶段为函数中存在的所有变量分配内存。
在为函数内的所有变量分配内存后,它会逐行执行代码。它会获取 num 的值,对于第一个变量来说,它等于 2,然后计算 ans。计算完 ans 后,它会返回该值,并将其赋给 square2。
一旦函数返回值,它将销毁其执行上下文,因为它已经完成了工作。
现在它将对行号 7 或 square4 变量执行类似的程序,如下所示。
一旦所有代码都执行完毕,全局执行上下文也将被销毁,这就是 JavaScript 在后台执行代码的方式。
调用堆栈
当 JavaScript 中调用一个函数时,JavaScript 会创建一个执行上下文。当我们在函数内部嵌套函数时,执行上下文会变得复杂。
JavaScript 借助调用栈来管理代码执行上下文的创建和删除。
堆栈(有时称为“下推堆栈”)是物品的有序集合,其中新物品的添加和现有物品的移除总是在同一端进行,例如一摞书。
调用堆栈是一种在调用多个函数的脚本中跟踪其位置的机制。
让我们举个例子
function a() {
function insideA() {
return true;
}
insideA();
}
a();
我们创建了一个函数“a”,它调用了另一个函数“insideA”,并返回 true。我知道这段代码很笨,什么也没做,但它能帮助我们理解 JavaScript 如何处理回调函数。
JavaScript 会创建一个全局执行上下文,全局执行上下文会在代码执行阶段给函数 a 分配内存并调用函数 a。
为函数a创建一个执行上下文,该执行上下文位于调用堆栈中全局执行上下文的上方。
函数 a将分配内存并调用函数insideA。函数 insideA 的执行上下文被创建,并位于函数 a 的调用栈之上。
现在,这个 insideA 函数将返回 true 并从调用堆栈中删除。
由于“函数 a”内没有代码,执行上下文将从调用堆栈中删除。
最后,全局执行上下文也从调用堆栈中删除。
参考
我希望这篇文章对您有所帮助。💪🏾如果您有任何疑问,请随时与我联系。
如需更多此类见解,请访问我的博客网站blog.webdrip.in
文章来源:https://dev.to/narottam04/how-javascript-works-visually-explained-269j