资讯专栏INFORMATION COLUMN

JS代码运行过程简述(一)

April / 1362人阅读

摘要:是动态语言,任何一段代码在执行之前都需要编译,它跟传统的语言不同,它不是提前编译的,编译结果也不能在分布式系统中进行移植。通过特定方法将的转化为一组机器指令,用来创建一个叫作的变量包括内存分配等,并将一个值存储到中。

JS 是动态语言,任何一段代码在执行之前都需要编译,它跟传统的语言不同,它不是提前编译的,编译结果也不能在分布式系统中进行移植。
但是JS引擎进行编译的步骤和传统的编译语言非常相似,在某些环节可能比预想的要复杂。

传统的编译

分词/词法分析(Tokenizing/Lexing)
这个过程会将由字符串组成的字符串分解成(对编程语言来说)有意义的代码块,这些代码块被称为词法单元(token)

e.g. var a = 2;
通常会被解析成var 、a、=、2、;
空格是否被当做此法单元,取决于空格在这门语言中是否具有意义

解析/语法分析(Parsing)
这个过程是将词法单元流(数组)转换成一个由元素逐级嵌套所组成的代表了程序语法结构的树(抽象语法树,Abstract Syntax Tree, AST)

var a = 2;

VariableDeclaration
|
|------ a
|------AssignmentExpression
    |-----2

代码生成
将AST转换成可执行代码的过程。

var a = 2;
通过特定方法将var = 2;的AST转化为一组机器指令,用来创建一个叫作a的变量(包括内存分配等),并将一个值存储到a中。

JS 编译

JS 的编译步骤和传统还是非常相似的,只是某些环节比较复杂,这里我详细说一下“预编译”,其他三个步骤同传统的编译

分词/词法分析(Tokenizing/Lexing)

解析/语法分析(Parsing)

预编译
首先先看一个例子:

function a(b) {    
      alert(b); 
    function b() {            
        alert(b);       
    }        
    b();    
}    
a(1);

答案先不说, 现在看具体的预编译过程:

预编译--全局
1). 创建Global Object对象(GO)

2). 查找变量声明

-> 如果GO上还没有该属性,则添加该属性,值为undefined  
-> 如果GO上已经有该属性,则不做任何处理 

3). 查找函数声明(eg. function foo () {})

-> 如果GO上还没有foo属性,则把函数赋值给foo属性  
 -> 如果GO上已经存在foo属性,则直接覆盖
 

预编译--函数
1). 函数运行前的一瞬间,生成Activation Object(活动对象),简称AO

2). 分析参数

 -> 把声明的参数形成AO的属性,值全为undefined  
 -> 接收实参,形成AO相应属性的值  

3). 分析变量声明

 -> 如果AO上还没有该属性,则添加该属性,值为undefined  
 -> 如果AO上已经有该属性,则不做任何处理  

4). 分析函数声明(eg. function foo () {})

 -> 如果AO上还没有foo属性,则把函数赋值给foo属性  
 -> 如果AO上已经存在foo属性,则直接覆盖

代码生成
JS执行过程简单的介绍完了,Do you get it?, 下面看之前例子分析:

function a(b) {    
      alert(b); 
    function b() {            
        alert(b);       
    }        
    b();    
}    
a(1);


// 分析如下
/*
 * 1. 创建GO对象(包含JS全局对象的内置对象Math、String、Date、etc)
 * 2. 查找变量声明,没有
 * 3. 查找函数声明,定义函数a, GO = {a: function () {}}
 * 4. 执行a(1)
 * // 以下为函数a运行前的编译
 * 5. 创建活动对象AO  AO={this, arguments}
 * 6. 分析形参 AO = {this, arguments, b: undefined}
 * 7. 接收实参 AO = {this, arguments, b: 1}
 * 8. 分析变量声明 AO = {this, arguments, b: 1}
 * 9. 分析函数声明 
     AO = {
         this
         argunments,
         b: function () {}
     }
 
 * // 执行
 * alert(b)  // function () { ... }
 * b()   // function () { ... }
 */

从以上分析很清晰就能够知道弹出两个function,是不是很简单啊。其实在执行b(),还有函数b也要编译哦,编译步骤同函数a,这里就不做分析了。
习题:

function a(b) {    
      alert(b); 
    b = function() {            
        alert(b);       
    }        
    b();    
}    
a(1);

自己试着分析一下,结果是1和function,你做对了么?难点:b = function () {}这个是一个赋值语句

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/83550.html

相关文章

  • JS每日题:简述下Vue.js的template编译过程

    摘要:问简述一下的编译过程先上一张图大致看一下整个流程从上图中我们可以看到是从后开始进行中整体逻辑分为三个部分解析器将模板字符串转换成优化器对进行静态节点标记,主要用来做虚拟的渲染优化代码生成器使用生成函数代码字符串开始前先解释一下抽象 20190215问 简述一下Vue.js的template编译过程? 先上一张图大致看一下整个流程showImg(https://image-static....

    NicolasHe 评论0 收藏0
  • 前端面试分享: 两年经验社招-阿里巴巴

    摘要:作者两年经验第一家任职的是个小公司第二家算是二线互联网公司各待了一年吧能有机会去阿里面试很惊喜先来和大家分享一下面试经历电话面试初探因为还在职的缘故电话面试从晚上点钟开始持续了半个小时左右一开始的时候特比紧张甚至声音略有些颤抖简单自我介绍做 作者两年经验, 第一家任职的是个小公司, 第二家算是二线互联网公司, 各待了一年吧... 能有机会去阿里面试很惊喜! 先来和大家分享一下面试经历....

    JowayYoung 评论0 收藏0
  • AngularJS简述

    流行框架 简介 angularjs是一款非常优秀的前端高级JS框架,由谷歌团队开发维护,能够快速构建单页web应用,化繁为简 无论是angularjs还是jQuery都是用原生JS封装的 库:对代码进行封装,调用封装的方法,简化操作 传统方式是用get方式获取元素,然后点方法 jQuery库实现了对获取方式的封装,对方法的封装 框架:提供代码书写规则,按照规则去写代码,框架会帮我们实现响应的功能...

    Jason 评论0 收藏0
  • 个网页的形成过程

    摘要:一个网页从我们输入网址到打开经历了以下步骤。如果没有或记录已经过期,则向域名解析服务器发送解析请求。服务器收到请求,产生响应,并将网页发送给负载均衡服务器。负载均衡服务器将网页传递给链处理,之后发回给我们的浏览器。 一个网页从我们输入网址到打开经历了以下步骤。 showImg(https://segmentfault.com/img/bVbpfj2?w=232&h=555); DNS...

    WelliJhon 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<