javascript 怎么让电脑认识它

122 阅读2分钟

javascript如何能够执行

学习和记录,请各位大佬指点。

众所周知,计算机只能理解0和1。那我们给浏览器js文件,为什么它能够执行?因为js引擎输出机器码,浏览器可以理解机器码。

javascript引擎由来

引擎有好多种,这里我们就讨论比较流行的 v8 ECMAScript引擎。由于早期的引擎比较简单,而且只能执行html、css。但是谷歌地图需要高性能的浏览器,然后2008年由c++编写的v8引擎诞生了。它主要应用在谷歌浏览器和nodejs,但是这个引擎究竟做了什么呢?

javascript引擎做了什么?

就做了这些 image.png

  • parser:词法分析器。
  • AST:abstract syntax tree 抽象语法树。这是一个可以将代码转换为AST的小工具astexplorer(虽然转换完看不懂,但是知道js被分解了)
  • interpreter:解释器。
  • profiler:分析器
  • compiler:编译器。
  • optimized code:优化代码。
  • bytecode:字节码

自己实现一个javascript引擎

const jsEngine = (code) => {
    return code.split(/\s+/);
}
jsEngine("const a = 'name'")
// ['const', 'a', '=', 'name']

完成喽。哈哈javascript引擎可不是这几行。它有很多处理在里面,只不过靠个人,特别是小趴菜是断然无法完成的,只是表达一下那个意思。当然,即便是高启强能实现,也不会让他做。因为每个人都写一个js引擎,那岂不是乱套了,没规范的js代码怎么能成为‘世界第一编程语言’。

interpreter vs compiler

解释器和编译器听起来就有点不分敌我。但是他们确实是两个东西。早期js引擎是只有解释器,它就相当于浏览器和计算机的翻译,它将js代码逐行翻译给浏览器,浏览器才知道要干嘛,这也是js被叫做解释型语言的原因。但是编译器其实也是翻译的作用,只不过它做了一些优化,让没有必要的执行省略,大大提高了代码执行效率。例如:

const sum = (a, b) => {
    return a + b;
}
for(let i=0; i<10000; i++){
    sum(1, 2)
}

// 解释器:打工人,老实执行每一次循环
// 编译器:董秘,sum(1, 2)都是3,那优化一下
    for(let i=0; i<10000; i++){
        3
    }

但是不能说解释器没有优点吧,就是快!因为啥?不分析不动脑啊。反之,编译器那就慢喽 v8则将两者的优点结合起来,就是just in time compiler(即时编译器),正如上图,profiler一直监听这个解释器,遇到可优化代码时并不直接解释为字节码,而是送给编译器优化。最后执行的优化代码效率大大提升。专业点就是代码转换成 AST 后先交给解释器进行处理,如果解释器监控到有部分 JavaScript 代码运行的次数较多,并且是固定结构,那么就会标记为热点代码并交给编译器进行处理,编译器会把那部分代码编译为二进制机器码,并进行优化,优化后的二进制代码交给 CPU 执行速度就会得到大幅提升。

so?

已经粗浅的知道了js如何被浏览器执行,并不是没用。了解了这些可以帮助我们写质量更高的代码。

隐藏类 & 内联缓存 给出两个关键字,如需更深入了解自省查阅,本人菜鸟,还有很多需要深入学习的知识。这里只说结论:

尽量使用字面量一次性初始化完整对象属性,因为对象的动态添加和删除对于对象内存分配和查询效率的开销极大。

# 利用 V8 深入理解 JavaScript 对象存储策略