一、概述
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(){}