JavaScript 代码的运行过程

365 阅读3分钟

一、概述

javascript的引擎的作用简单的来讲,就是能够读懂javascript代码,并且准确地给出运行结果的程序,比如说,当我们写 var temp = 1+1; 这样一段代码的时候,javascript引擎就能解析我们这段代码,并且将temp的值变为2。

Javascript引擎的基本原理是: 它可以把JS的源代码转换成高效,优化的代码,这样就可以通过浏览器解析甚至可以被嵌入到应用当中。

为什么会有那么多引擎?那是因为他们每个都被设计到不同的web浏览器或者像Node.js那样的运行环境当中。他们唯一的目的是读取和编译javascript代码。

常见的解析器
Mozilla浏览器 -----> 解析引擎为 Spidermonkey(由c语言实现的)
Chrome浏览器 ------> 解析引擎为 V8(它是由c++实现的) 
Safari浏览器 ------> 解析引擎为 JavaScriptCore(c/c++) 
IE and Edge ------> 解析引擎为 Chakra(c++) 
Node.js     ------> 解析引擎为 V8

JavaScript动态解析的过程分为两个阶段—— 编译阶段、执行阶段

注意: 在javascrip如果遇到错误,会直接跳出当前的代码块,直接执行下一个script代码段,因此在同一个script内的代码段有错误的话就不会执行下去。但是它不会影响下一个script内的代码段。

注意: 编译阶段除了词法分析 语法分析 现在v8引擎还会根据ast生成字节码。早期是直接从ast转成机器码。所以每次拿到js文件的时候都会编译。

<script>
  var a = 'a'
  console.log(a)
  console.log(a+b)
</script>
<script>
    var b = 'b'
  console.log(b)
</script>

编译阶段&执行阶段

词法分析:esprima.org/demo/parse.…)就是分析代码或函数的一些变量,声明的处理.从字符流(char stream)转换为记号流(token stream)这些代码块被称为词法单元。例如,考虑程序 var a = 2;。这段程序通常会被分解成 为下面这些词法单元:var、a、=、2 、;。空格是否会被当作词法单元,取决于空格在 这门语言中是否具有意义。

语法分析 :转化AST (Abstract Syntax Tree)解释器再根据语法树转成机器码、或者字节码。

注意: 在此过程中,如果源代码不符合语法规则,则会终止,并抛出“语法错误”

var answer = 1 + 2 * 3;
var answer = 1;

function fn(func){
    console.log(func);
    function func(){
        console.log(func);
    // }
}
fn(1);

Error: Line 10: Unexpected end of input


代码生成: 将 AST 转换为可执行代码的过程称被称为代码生成。

在编译阶段,变量和函数会被存放到变量环境中,变量的默认值会被设置为 undefined;在代码执行阶段,JavaScript 引擎会从变量环境中去查找自定义的变量和函数

function test(a,b){
  console.log(a);
  var c = 123;
  console.log(c);
  function a(){};//这个是函数声明
  console.log(b);
  var b = function c(){};//这个是函数表达式
  console.log(b);
  }
  test(1,3);

1:创建一个AO对象(activation object),AO{}

2:   将函数内所有的形参和变量声明(的名)储存到ao对象中,value为undifined

AO{
	  a:undefined,
	  b:undefined,
	  c:undefined
  }

3.将形参实参统一

AO{
	a:1,
	b:3,
	c:undefined
}

4.函数声明提前

AO{
  a:function a(){},
  b:3,
  c:undefined
  }

5.执行结果

function a(){},

123,

3,

function c(){}