0
点赞
收藏
分享

微信扫一扫

JavaScript知识点

虽然通常将js归类为“动态”或“解释执行”语言,但其实也可把它看成是一门编译语言。只不过这个所谓的编译与传统的编译语言不同,它不是提前编译的,编译结果也不能在分布式系统中进行移植。对于js来说,它的编译过程不是发生在构建之前的,大部分情况下编译发生在代码执行前的几微秒甚至更短的时间内。甚至是代码执行中

为甚么怀疑js不是解释型语言?

如果是解释型语言,变量声明提升为什么会发生?
JIT(及时编译)做代码优化(同时生成编译版本);解释型语言无法做到这些(解释型语言几乎在执行后一瞬间就开始,几乎没有任何代码优化)

编译型语言 vs 解释型语言

编译型语言是代码在运行前编译器将人类可以理解的语言(编程语言)转换成机器可以理解的语言
解释型语言也是人类可以理解的语言(编程语言),也需要转换成机器可以理解的语言才能执行,但是是在运行时转换的。所以执行前需要解释器安装在环境中;但是编译型语言编写的应用在编译后能直接运行。

许多人认为解释型语言意味着当遇到程序中行号为xyz时直接将其传给CPU就能运行;但是事实不是这样。所有的编程语言都是为人类创建的。他们是人类能够理解的。你必须将编程语言转换为机器语言。编译器获取整个代码,转换它,做合适的优化并且创建一个可以运行的输出文件。编译器根据上下文来转换语句。

声明提升

js的声明提升:在函数作用域内的任何变量的声明都会被提升到顶部并且是undeinfed值。
所以JavaScript引擎解释同样的脚本文件两次?做完所有的声明提升然后执行代码?还是先编译整个代码然后运行它?这两种情况都不对。

下面是js处理声明的过程:
一旦V8引擎进入一个执行具体代码的执行上下文(函数),它就对代码进行词法分析或者分词。这意味着代码将被分割成像foo = 10这样的原子标记。
在对当前的整个作用域分析完成后,引擎将解析成一个AST(抽象语法书)的翻译版本。
引擎每一次遇到声明,它就把声明传到作用域来创建一个绑定。对每一次声明它都会为变量分配内存。只是分配内存而不是把代码修改成声明提升。正如你所知道的,在JS中分配内存意味着将默认值设为undefined。
在这之后,引擎每一次遇到赋值或者取值,它都会通过作用域查找绑定。如果在当前作用域中没有查找到就接着向上级作用域查找直到找到为止。
接着引擎生成CPU可以执行的机器码。
最后, 代码执行完毕。

所以变量提升不过是执行上下文的游戏,而不是网站描述的代码修改。在执行任何语句之前,解释器就已经从运行上下文创建的作用域中找到变量的值了。
举报

相关推荐

0 条评论