javascript从定义到执行 你不知道的那些事
这篇文章主要了JavaScript从定义到执行的过程,深入了JS引擎的工作机制。对于初学者和感兴趣的小伙伴们来说,这是一篇非常有价值的参考文章。
在学习JS引擎工作机制之前,我们需要了解几个关键概念,如执行环境栈、全局对象、执行环境、变量对象、活动对象、作用域和作用域链等。这些概念是JS引擎工作的核心组件,它们在一起构成了JavaScript的运行环境。
通过一个简单的demo,我们可以更好地理解和应用这些概念。这个demo是一个闭包,执行结果是4。我们将分全局初始化、执行函数A、执行函数B三个阶段来分析JS引擎的工作机制。
一、全局初始化
当JS引擎进入一段可执行的代码时,首先需要创建一个全局对象,这个对象全局只存在一份,它的属性在任何地方都可以访问。然后,JS引擎需要构建一个执行环境栈,并创建一个全局执行环境EC,并将其压入执行环境栈中。还要创建一个与EC关联的全局变量对象VO,并把VO指向全局对象。此时的执行环境栈中只有一个全局执行环境。
二、执行函数A
当执行进入函数A时,JS引擎需要完成一系列工作。创建函数A的执行环境EC,并将其推入执行环境栈的顶部。执行环境栈中有两个执行环境,分别是全局执行环境和函数A执行环境。在函数A中,可以访问到全局变量对象VO中的属性和方法,同时也可以定义局部变量和内部函数。
三、执行函数B
当执行进入函数B时,JS引擎需要为函数B创建一个执行环境EC,并将其推入执行环境栈的顶部。在函数B中,可以访问到函数A的变量对象AO中的变量x和全局变量对象VO中的属性。由于闭包的存在,函数B可以访问到函数A的变量对象AO中的变量x的值。
JavaScript从定义到执行的过程是一个复杂而有趣的话题。通过深入了解JS引擎的工作机制和相关概念,我们可以更好地理解和应用JavaScript。这篇文章通过简单的demo和生动的描述,让读者更容易理解JavaScript的工作原理,是一篇非常有价值的参考文章。
希望这篇文章能激发更多人对JavaScript的兴趣,并深入JavaScript的奥秘。也希望大家能通过学习和实践,不断提高自己的JavaScript技能,为Web开发做出更多的贡献。我们来深入理解JavaScript中的函数和作用域链。在JavaScript中,每个执行环境都拥有一个作用域链,它主要用于标识符的。当一个新的执行环境被创建时,它的作用域链就会被初始化为当前运行函数的scope所包含的对象。
当我们创建函数A时,JS引擎会同步创建一个活动对象AO(A),这个活动对象包含了函数A的形参、arguments对象、this对象以及所有的局部变量和内部函数的定义。然后,这个活动对象AO会被推入到函数A的作用域链的顶端。值得注意的是,函数A的scope会指向定义它时的环境,也就是全局变量对象VO(G)。函数A的作用域链包括AO(A)和VO(G)。
接着,我们在函数A中定义了函数B。当函数B被定义时,JS引擎同样会为它添加一个scope属性,这个scope指向了定义函数B时的环境,也就是函数A的活动对象AO(A)。因为AO(A)位于作用域链的前端,所以函数B的scope实际上指向了函数A的整个作用域链。此时的执行环境栈结构如下:
ECStack(执行环境栈)= [
EC(G)(全局执行环境),EC(A)(函数A的执行环境)],其中EC(A)的作用域链为AO(A)-VO(G)。
当我们在函数A中执行函数B时,JS引擎会按照以下步骤进行操作:首先创建函数B的执行环境EC,并将EC推入执行环境栈的顶部。此时执行环境栈中有两个执行环境:全局执行环境和函数B的执行环境。然后创建函数B的作用域链,并初始化为函数B的scope所包含的对象,也就是函数A的作用域链。接着创建函数B的活动对象AO,包含B的形参、arguments对象和this对象。此时的执行环境栈结构为:ECStack = [EC(G), EC(B)],而函数B的作用域链为AO(B)-AO(A)-VO(G)。
当函数B被执行后返回结果给变量C时,我们实际上是在执行C的函数体,也就是执行了函数B的调用并传入了参数。此时JS引擎会按照上述步骤创建相应的执行环境和作用域链。值得注意的是,当函数A执行完毕后,它的执行环境会从执行环境栈中删除,只剩下全局执行环境。而函数B的作用域链则始终存在于其执行环境中。这就是JavaScript中函数和作用域链的基本工作原理。未来的ECStack,将会以全新的面貌呈现。在这个执行环境栈中,每一个环境都有其独特的结构和运行机制。
我们创建一个名为B的执行环境,并将其置于作用域链的顶端。这个环境有一个作用域链,指向函数A的作用域对象AO(A),然后再连接到全局对象VO(G)。我们创建函数B的活动对象AO(B),其中包含变量z、参数列表以及全局对象window等。这个作用域链被初始化为指向AO(B),然后链接到B的作用域链中的AO(A),最终到达VO(G)。这意味着在函数B中,我们可以访问到函数A的作用域以及全局对象中的变量。
当函数A执行完毕后,它的执行环境会从栈顶被删除,取而代之的是其他执行环境。全局执行环境EC(G)包含全局变量对象VO,其中定义了全局变量x和函数A等。函数A的scope被定义为其所在的全局对象VO(G)。这意味着在函数A中,我们可以访问到全局对象中的所有变量和函数。
当函数B执行表达式“x+y+z”时,它首先会在自己的活动对象AO(B)中查找变量x、y和z。如果找不到这些变量,它会沿着作用域链向上查找,直到找到为止。在这个例子中,变量x和y会在AO(A)中找到,而变量z则在AO(B)中找到。表达式的结果为2+1+1=4。
理解了JavaScript引擎的工作机制后,我们可以利用这些知识来优化我们的代码。例如,如果我们的代码嵌套很深并且频繁引用全局变量,那么每次引用都会使JS引擎在整个作用域链中进行查找。我们可以通过将频繁使用的全局变量存储在更接近作用域链顶部的位置来提高查找效率。除此之外,还有很多其他的优化方法。本文将此作为启示,更多的优化方法等待我们去和实现。
了解JavaScript的作用域和变量查找机制是非常重要的,它能帮助我们更好地理解和优化代码。希望本文能对大家的学习有所帮助。接下来,我们将继续深入JavaScript的更多特性和最佳实践,以帮助我们更有效地编写代码。本文的内容就到这里结束了,希望对大家有所启发。接下来还有更多精彩内容等待大家去学习和。让我们共同学习进步吧!
平面设计师
- javascript从定义到执行 你不知道的那些事
- 如何使用纯PHP实现定时器任务(Timer)
- PHP基于curl实现模拟微信浏览器打开微信链接的方
- 基于PHP-FPM进程池探秘
- 解决layui的使用以及针对select、radio等表单组件不
- js正则相关知识点专题
- JS实现移动端按首字母检索城市列表附源码下载
- JQuery Ajax WebService传递参数的简单实例
- 比例尺、缩略图、平移缩放之百度地图添加控件
- javascript中select下拉框的用法总结
- 详解PHP+AJAX无刷新分页实现方法
- JavaScript ES6中CLASS的使用详解
- 微信小程序之下拉列表实现方法解析(附完整源
- 浅谈VUE单页应用首屏加载速度优化方案
- 简单实现js间歇或无缝滚动效果
- 彻底学会Angular.js中的transclusion