前言最开始的时候,Javascript的圣经——MDN明确地说Javascript是一个解释型语言。但是下面几点仍然会让Javascript是否真的是一个解释型语言产生疑问:如果是解释型语言那么声明提升为什么会发生JIT做代码优化;解释型语言无法做到这些。
编译型语言 VS 解释型语言主要问题是没有团体或者组织规定这些;例如:编译型语言和解释型语言的定义以及如何划分。

而这两个都是概念。所以根据概念,编译型语言是代码在运行前编译器将人类可以理解的语言转换成机器可以理解的语言。解释型语言也是人类可以理解的语言,也需要转换成机器可以理解的语言才能执行,但是是在运行时转换的。
所以执行前需要解释器安装在环境中;但是编译型语言编写的应用在编译后能直接运行。
许多人认为解释型语言意味着当遇到程序中行号为xyz时直接将其传给CPU就能运行;但是事实不是这样。所有的编程语言都是为人类创建的。他们是人类能够理解的。
你必须将编程语言转换为机器语言。编译器获取整个代码,转换它,做合适的优化并且创建一个可以运行的输出文件。
编译器根据上下文来转换语句。
声明提升在函数作用域内的任何变量的声明都会被提升到顶部并且是undeinfed值。下面是Javascript处理声明的过程:一旦V8引擎进入一个执行具体代码的执行上下文,它就对代码进行词法分析或者分词。这意味着代码将被分割成像foo = 10这样的原子标记。
在对当前的整个作用域分析完成后,引擎将解析成一个AST的翻译版本。引擎每一次遇到声明,它就把声明传到作用域来创建一个绑定。对每一次声明它都会为变量分配内存。只是分配内存而不是把代码修改成声明提升。
正如你所知道的,在JS中分配内存意味着将默认值设为undefined。在这之后,引擎每一次遇到赋值或者取值,它都会通过作用域查找绑定。如果在当前作用域中没有查找到就接着向上级作用域查找直到找到为止。接着引擎生成CPU可以执行的机器码。
最后, 代码执行完毕。所以变量提升不过是执行上下文的游戏,而不是网站描述的代码修改。在执行任何语句之前,解释器就已经从运行上下文创建的作用域中找到变量的值了。Javascript中的即时编译编译型和解释型语言最重要的区别是编译语言话很长的时间来准备执行。
因为它需要对整个代码进行词法分析、做一些极致的优化等工作。另一方面解释型语言几乎在执行后一瞬间就开始,但是没有任何代码优化。所以没一条语句都是分开转换的,看下面这一段代码:在编译型语言中sum += i部分在循环运行时已经编译成了机器码,机器码将直接运行一千次。
但是在解释型语言中,他会在执行时将sum += i解释一千次。所以因为对相同的代码进行一千次转换会造成非常大的性能损耗。总结Javascript代码需要在机器上安装一个工具才能执行。
这是解释型语言需要的。编译型语言产品能够自由地直接运行。声明提升等不是代码修改。在这个过程中没有生成中间代码。
这只是JS解释器处理事情的方式。即时编译是唯一一点我们可以对Javascript是否是一个解释型语言提出疑问的理由。但是即时编译不是纯粹的编译器,它在执行前进行编译。
而且JIT知识Mozilla和Google的开发人员为了在他们的浏览器产品中提升性能才引入的。Javascript或TC39从来没有要求这样做。因此,虽然Javascript执行时像是编译过的或者是一种混合,但是我觉得说Javascript是一个解释型语言要好过说是一个编译型语言或者最近很多人说的一个混合型的语言。


