JavaScript是解释型语言,也就是说,我们的js代码会通过一个解释器来进行解释执行,这个解释器我们称为js引擎,因为我们的浏览器也能执行js,所以浏览器里面也有js引擎,不同的浏览器有不同的js引擎,比如chrome的V8,safari的webkit,IE浏览器的Trident等。
js引擎的执行需要走三个步骤,第一是进行语法分析,这个比较简单,就是看你的代码格式是不是正确的,比如,如果你少了个大括号,就会被报错。
第二步是进行预编译,预编译会把代码当中使用的变量,定义的函数解析出来,确定出环境中的变量和函数等信息,也就是这个过程会导致js变量提升的问题,比如:
var a = 1; // 变量声明
function b(y) { // 函数声明
var x = 1;
console.log('so easy');
};
var c = function() { // 是变量声明而不是函数声明!!
// ...
}
b(100);
当js引擎进行预编译的时候,首选会生成一个GO(Global Object,这里是window):
GO/window = {
//页面加载创建GO同时,创建了document、navigator、screen等等属性
a: undefined,
c: undefined,
b: function(y){
var x = 1;
console.log('so easy');
}
}
第三步就是解释并执行代码,直到遇到b(100)
,代码执行后活动对象变成了:
GO/window = {
//页面加载创建GO同时,创建了document、navigator、screen等等属性
a: 1,
c: function() {
// ...
},
b: function(y){
var x = 1;
console.log('so easy');
}
}
当执行b(100)
的时候,js引擎会针对b函数进行预编译,创建AO(Active Object)对象:
AO = {
//创建AO同时,创建了arguments等等属性,此处省略
y: 100,
x: undefined
}
然后执行b(100)
。
之后会一直重复进行预编译=>代码执行的过程。