深入理解JavaScript之---(JavaScript的编译过程)

来源:互联网 发布:大连软件学校 编辑:程序博客网 时间:2024/06/05 16:42

       上周团队代码走读的时候,keke给我的代码提了一个建议:变量声明的时候所有的变量都要在使用前声明,虽然JavaScript没有强制要求这么做,但是这么做可以让程序易于阅读,容易发现那些没有声明的变量。

       他还提到JavaScript会预先给变量分配内存,这到底是怎么回事呢?这激起了我的好奇心,要想真正的理解一门语言不仅要知其然还要知其所以然。通过查找资料终于有所理解了。

       编程语言有编译语言解释语言之分。不管是什么语言都要先翻译成机器可以识别的语言,编译语言和解释语言只是翻译成机器语言的时间不同而已。(我看到过一个有趣的比喻:编译语言就像是先做好一桌子菜然后再开吃,解释语言就像是吃火锅,边煮边吃,很耗时的哟)。

       编译语言指的是代码在执行之前会先编译成可执行文件,可执行文件就是计算机可以识别的机器语言,即二进制文件(这些可执行文件是一次编译所得,但是可以多次使用),有了可执行文件之后计算机就可以识别这些可执行文件,从而实现高级语言所编写的代码的功能。很明显,编译语言的优点就是执行速度快,缺点是跨平台性差(因为不同的平台对可执行文件的要求不一样,也就是所需要的编译器不一样),C、C++就是典型的编译语言。

        解释语言就不会先编译成可执行文件,而是一边把高级语言解释编译、翻译)成机器语言一边执行代码。优点是:不依赖平台,会根据不同的平台对代码语句进行解释;缺点是:执行速度慢。

        现在因为高级语言的种类越来越多,这两个概念都很模糊了,我们已经没必要纠结一门语言到底是属于编译语言还是解释语言。我比较赞同“重要的是语言的工作机理而不是下定义”的观点,透过现象看本质,理解JavaScript的工作机制才是王道。

        首先了解一下传统的编译语言的源代码在执行之前经历的三个步骤(编译过程):

              1.分词(词法分析)。编译器会将代码(由字符组成的字符串)分解成有意义的代码块,也就是词法单元。例如,程序var a=1;这段程序会被分解成为这些词法单元:var、a、=、2、;。空格是否会被当做词法单元,取决于空格在这门语言中是否具有意义。

               2.解析(语法分析)。这个过程是将词法单元流(由上一个步骤分解出来的词法单元组成)转换为由元素逐级嵌套所组成的结构树,它代表的是程序的语法结构,被称为“抽象语法树(AST)”。(这些都是编译原理的知识,要深入研究可以参考一些著名的大学教材)

               3.代码生成。这个过程将AST树转换为可执行代码也就是一组机器指令,这个过程和使用的平台有密切的关系。

 
       JavaScript引擎比起以上三个步骤来说要复杂很多,这需要进一步的学习理解。此篇博客只是初学者的一点学习记录。

       JavaScript的编译过程不是发生在程序整体执行之前的,也就是说按照编译语言和解释语言分类的话,JavaScript属于解释语言,它没有生成可执行文件的这一过程。所以JavaScript的执行过程是比较慢的,有的JavaScript引擎为了改善它的执行速度就使用JIT技术(just in time)来保证它的性能,(这里稍微提一下,JavaScript引擎是搜索引擎功能的一部分,因为不同的搜索引擎自己编写的JavaScript引擎不同,所以这里就又有一个JavaScript的兼容性问题)。

      现在不得不提出三个重要的名词:引擎(从头到尾负责整个JavaScript程序的编译及执行过程)、编译器(负责语法分析及代码生成,不清楚的参看前面的编译过程)、作用域(是一套用于确定在哪里查找变量及如何查找变量的规则)  。了解他们有助于理解JavaScript的工作机制。

       以 var a=1;这段程序为例看编译器的执行过程:1.遇到var a,编译器会首先在同一个作用域的集合中寻找该名称的变量,如果有,编译器会忽略该声明,继续进行编译;如果没有,编译器会在当前作用域的集合中声明一个新的变量,命名为 a 。2.接下来编译器会为引擎生成运行时需要的代码,用来处理a=1这个赋值操作。引擎运行时会在当前作用域集合中查找一个叫做a的变量,如果有引擎就会使用这个变量;如果没有,引擎会继续向上一级作用域查找,如果引擎最终找到了变量a,就会将1赋值给它,否则引擎就会抛出一个异常。

(也就是说变量的赋值操作执行的是两个动作)

关于JavaScript的内部机制还有很多,未完待续......


这篇博客对JavaScript的工作流程总结的很清楚http://blog.csdn.net/cxiaokai/article/details/7552653

0 0
原创粉丝点击