JavaScript内部是这样运行
编译阶段词法分析(Lexing)
简单举个例子:c = b - a 转换为
语法分析(Parsing)
AST大概是下面的样子:
生成可执行代码
执行阶段接下来,我们以一个简单例子进行分析。
1. JS引擎创建一个全局对象(Global Object) 这个对象全局只存在一份,它的属性在任何地方都可以访问,它的存在伴随着应用程序的整个生命周期。全局对象在创建时,将Math,String,Date,document 等常用的JS对象作为其属性。由于这个全局对象不能通过名字直接访问,因此还有另外一个属性window,并将window指向了自身,这样就可以通过window访问这个全局对象了。用伪代码模拟全局对象的大体结构如下:
2. JS引擎会创建一个执行环境栈(Execution Context Stack)
上图中的羽毛球1一定是先放入栈中,然后是羽毛球2,以此类推,而出栈时,一定是羽毛球5先拿出来,然后是羽毛球4,以此类推,这种方式和栈存取数据的方式如出一辙。
好了好了,扯远了。我们接着往下说,在这只需知道执行环境栈是怎样存取数据的就行。 3. 创建全局执行上下文(Execution Context) 到这你可能会问,上下文是个啥玩意? 是啊,上下文是个什么鬼啊? 上下文不是玩意,也不是什么鬼。 执行上下文可以理解为当前代码的执行环境。JS所有代码都会在自己的上下文环境下运行。 说到上下文,你可能会有这样的疑惑:上下文不就是作用域吗? 老铁,我肯定的告诉你,上下文不是作用域。的确,在JS里,这还真是个很难区分的东东。不过现在我还不能马上道出他们的区别,因为作用域的知识,我们还没有涉及, 那在JS中会有几种执行环境呢? 大概有3种:
因此在一个JavaScript程序中,必定会产生多个执行上下文。 go on... 4. 全局上下文推入执行环境栈底 5. 代码开始从上往下执行,这里我们暂且不谈标识符处理,当代码执行到bar(),生成bar执行上下文,推入栈中 6. 代码执行到foo(),生成foo执行上下文,推入栈中 7. foo()执行完,foo执行上下文出栈 8. bar()执行完,bar执行上下文出栈 9. 全局上下文执行上下文出栈 我们用图走一下js执行流程,是这样的:
小伙伴们,现在是不是对JS执行流程有了一个整体认识,下面我们来说点更有意思的。 上下文执行细节我们先看整体了解下
创建阶段1. 创建变量对象(Variable Object)创建变量对象,依次经历了以下几个步骤
变量提升看到这,我觉得你对变量提升具体是什么以及如何实现的应该了解的一清二楚了。 是不是呢? 我们来一道题测试下
第一处是undefined,第二处是[Function: baz],是不是很简单? 下面我用代码简单模拟下上面的过程
变量对象大概是这样的
2. 确定作用域链作用域链是由当前作用域与上层一系列父级作用域组成,作用域的头部永远是当前作用域,尾部永远是全局作用域。作用域链保证了当前上下文对其有权访问的变量的有序访问。 我们先简单了解下,详细的我们会在彻底搞懂JavaScript作用域中谈到。
上面的对于我们来说很简单,是吧?没错这就是作用域链的应用。 我们简单模拟下
3. 确定this指向谈到this,大家是不是感到很兴奋,平时写代码时,被这家伙整的晕头转向的,这回我们终于可以揭开this的神秘面纱了,搞清楚它在JS到底是怎样的存在,不过客官别着急,我们这里先不介绍this,因为关于this的内容太多了,我们得慢慢去品味它,这里先记住,this是在执行上下文创建阶段确定的。 this传送门 全局上下文全局上下文有些特殊,其变量对象永远是window,this永远指向window(在浏览器中,Node中不是)。 即
执行阶段在执行阶段变量对象(Variable Object)变为活动对象(Active Object)。
执行阶段JS引擎会进行变量赋值、函数引用、执行其他代码,执行顺序取决于代码的位置。 我们就聊到这吧。 喝杯茶, 休息一下。 |
prettyEcho added JS interesting labels 9 days ago
Pomelo1213 commented 3 hours ago
这个地方baz到底是怎样的?
这里baz不应该是undefined吗?相同名字的变量和函数,函数会声明前置,这个地方是覆盖baz吗?博主,能解下疑惑吗? |
JavaScript内部是这样运行的更多相关文章
- JavaScript内部原理实践——真的懂JavaScript吗?(转)
通过翻译了Dmitry A.Soshnikov的关于ECMAScript-262-3 JavaScript内部原理的文章, 从理论角度对JavaScript中部分特性的内部工作机制有了一定的了解. 但 ...
- JavaScript 对引擎、运行时、调用堆栈的概述理解
JavaScript 对引擎.运行时.调用堆栈的概述理解 随着JavaScript越来越流行,越来越多的团队广泛的把JavaScript应用到前端.后台.hybrid 应用.嵌入式等等领域. 这篇文 ...
- JavaScript闭包的底层运行机制
转自:http://blog.leapoahead.com/2015/09/15/js-closure/ 我研究JavaScript闭包(closure)已经有一段时间了.我之前只是学会了如何使用它们 ...
- 解读JavaScript 之引擎、运行时和堆栈调用
转载自开源中国 译者:Tocy, 凉凉_, 亚林瓜子, 离诌 原文链接 英文原文:How JavaScript works: an overview of the engine, the runtim ...
- 解读 JavaScript 之引擎、运行时和堆栈调用
https://www.oschina.net/translate/how-does-javascript-actually-work-part-1 随着 JavaScript 变得越来越流行,很多团 ...
- JavaScript忍者秘籍——运行时代码求值
1. 代码求值机制 JavaScript中,有很多不同的代码求值机制. ● eval()函数 ● 函数构造器 ● 定时器 ● <script>元素 - 用eval()方法进行求值 作为定义 ...
- JavaScript内部原理系列-变量对象(Variable object)
概要 我们总是会在程序中定义一些函数和变量,之后会使用这些函数和变量来构建我们的系统.然而,对于解释器来说,它又是如何以及从哪里找到这些数据的(函数,变量)?当引用一个对象的时候,在解释器内部又发生了 ...
- 如何用JavaScript判断前端应用运行环境(移动平台还是桌面环境)
我们部署在某些云平台或者Web服务器上的前端应用,既可以用PC端浏览器访问,也可以用手机上的浏览器访问. 在前端应用里,有时候我们需要根据运行环境的不同做出对应处理.比如下面这段逻辑,如果判断出应用当 ...
- Javascript中计算脚本运行的时间
console.time("timer名字") 其他脚本 console.timeEnd("timer名字"); 运行后结果为: timer名字: 运行时间
随机推荐
- The Apache Tomcat Servlet/JSP Container
1.Tomcat部署的场景分析 通常,我们对tomcat单机部署需求可以分为几种: 单实例单应用 (一个tomcat 一个web应用) 单实例多应用 (一个tomcat多个应用) 多实例单应用 (多个 ...
- 基于js原生封装的点击显示完整文字
基于js原生封装的点击显示完整文字 (function(window) { var inner = ''; var showCont_s = function(ele) { this.init.app ...
- 揭密 Vue 的双向绑定
Vue 中需要输入什么内容的时候,自然会想到使用 <input v-model="xxx" /> 的方式来实现双向绑定.下面是一个最简单的示例 剖析Vue原理& ...
- 简述在php中 = 、==、 === 的区别(简述在php中 等于 、双等于、 三等于 的区别)
= 是赋值:就是说给一个变量赋值 == 是轻量级的比较运算,只看值不看类型 === 是重量级的比较运算,既看值,也看类型,要绝对相等才会为true
- linux下mysql的权限设计总结
1,进入mysql,终端中输入 mysql -u 用户名 -p .enter键后,提示输入密码. 2,执行grant all privileges on xxxdb.* to usertest@& ...
- nginx+django线上部署
(一):背景在线 由于现在工作的需要,我需要使用Python来进行一个网站后台的开发,python之前接触过其语法的学习,基本的东西已经掌握,但是当时自学的时候是学得python3.5,而现在要使用p ...
- haystack(django的全文检索模块)
haystack haystack是django开源的全文搜索框架 全文检索:标题可以检索,内容也可以检索 支持solr ,elasticsearch,whoosh 1.注册app 在setting. ...
- stark组件(2):提取公共视图函数、URL分发和设置别名
效果图: Handler类里处理的增删改查.路由分发.给URL设置别名等包括以后还要添加的很多功能,每一个数据库的类都需要,所以我们要把Handler提取成一个基类.提取成基类后,每一个数据表都可以继 ...
- 二分法:CF371C-Hamburgers(二分法+字符串的处理)
Hamburgers Time Limit:1000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u Desc ...
- HDU 3966 Aragorn's Story 树链拋分
一.写在前面 终于开始开坑link-cut-tree这个了,对于网上找到的大佬的前进路线,进行了一番研发,发现实际上可以实现对于树链拋分的制作.经历了若干长时间之后终于打了出来(为什么每次学什么东西都 ...



