代码编译过程:
1.检查通篇的语法错误,若有错误则不编译执行
2.预编译
3.解释一行,执行一行
栈和堆:
栈区域:存储数据为基本数据类型,当调用堆中的数据时,调用的是地址
栈遵循"先进后出,后进先出"的规则,或称LIFO (“Last In First Out”) 规则。
堆区域:存储数据为引用数据类型,也可是基本数据类型 (为赋值时数据在堆中重新开辟新地址)
执行上下文 EC (execution context)
分类:
1.全局上下文:打开一个新的窗口就会创建一个全局上下文(关闭即销毁)只能创建一个 打开一个创建一个
2.局部(函数)上下文:调用函数时就会创建一个局部上下文(函数执行完毕 销毁) 同一个函数被多次调用,都会创建一个新的上下文(因地址不同)。
**3.eval上下文(了解):**会解析字符中的js代码
提升:函数声明会整体提升,变量表达式只有声明提升,赋值不提升
*变量提升:var声明的变量(除了函数内),只提升变量的声明
*函数提升:(需为字面量声明)提升整个函数体 提升只会在函数内提升 不会提升为全局
先变量提升(将所有变量提升完在进行函数的)在进行函数提升
函数提升优先级高于变量提升
全局执行上下文:找函数体与var声明变量
在页面执行(window=GO(global object即全局上下文))
局部执行上下文:
1.创建局部对象AO(Active Object在函数执行之前进行的一个步骤) 开始调用才有AO
2.预编译
A: 寻找形参 , 变量声明(var)
B:形参 , 变量赋值
C:形参和实参相统一(实参赋值给形参)
D:函数提升并赋值
E:确定this的指向(由调用者确定)
F:确定作用域(词法环境:在哪里声明,就确定在哪个作用域)
G;确定AO的(初始化)作用域链
3.执行函数体代码
例:
function test(a) {
console.log(a); // function a() {}
var a = 1;
console.log(a); // 1
function a() {};
console.log(a); // 1
var b = function() {};
console.log(b); // function() {}
function d() {}
}
```javascript
test(2);
AO的过程如下:
AO = {
a: (寻找函数的形参和变量声明)undefined ->(把实参的值赋值给形参)2 -> (寻找函数体声明,并赋值)function a() {} -> (执行) 1
b: (寻找函数的形参和变量声明)undefined -> (执行)function() {}
d: (寻找函数体声明,并赋值)function d() {}
}
```javascript
var i = 1;
function f70() {
console.log(i); //
let i = 0; //暂时性死区
//告知当前AO拥有该变量
}
f70();
函数内部和外面有相同的变量,如果函数内在变量赋值之前,如果函数内部有变量声明则用函数内部的变量声明,没有则用外面的同名变量