什么是执行上下文和执行栈?
执行上下文分为:
- 全局执行上下文
- 函数执行上下文
- eval函数执行上下文
执行栈也叫调用栈,遵从后进先出LIFO的顺序。
首次运行js代码时,会在调用栈中push进去一个全局执行上下文,每当发生函数调用,调用栈中会push进去一个函数执行上下文,函数执行完毕后,该函数的执行上下文会pop出调用栈,上下文的控制权将交给下一个执行上下文。
执行上下文的创建和执行过程是哪些?
执行上下文的创建有三个步骤:1.确定this的值 2.创建词法环境 3.创建变量环境
This 的绑定
- 全局执行上下文中,this指的是全局对象,在浏览器中this指的是window对象,在nodejs中,this指的是这个文件module对象。
- 函数执行上下文中,this的值取决于函数的调用方式。
词法环境
由两部分组成
- 环境记录:存储变量和函数声明的实际位置
- 对外部环境的引用:可以访问外部的词法环境
词法环境分为两种
- 全局环境:对外部环境的引用为null,环境记录里有全局对象以及全局对象的方法和属性,以及用户自定义的全局变量
- 函数环境:用户在函数中定义的变量被存在环境记录中,包含arguments对象。对外部环境的引用可以是全局环境,也可以是包含这个函数环境的外部函数环境。
变量环境
变量环境也是词法环境的一种,也有环境记录和外部环境引用。不同的是,词法环境记录const、let关键词声明的变量,变量环境只记录var关键词声明的变量。
上下文的执行阶段
此阶段,完成对所有变量的分配,最后执行代码。
变量提升
函数提升>变量提升
jsx
foo(); // foo2
var foo = function() {
console.log('foo1');
}
foo(); // foo1,foo重新赋值
function foo() {
console.log('foo2');
}
foo(); // foo1
特别注意,同一个作用域中存在多个同名函数的声明,后面的会替换前面的声明。