1,执行上下文
执行上下文是指代码运行的环境。每个上下文都有一个关联的变量对象,这个上下文中定义的所有变量和函数都存在于这个对象上。
- 函数执行上下文:函数执行时关联的上下文对象为AO(Activation Object)。函数执行上下文会在函数调用时创建
- 全局执行上下文:也表示全局作用域,GO(Global Object)
- 在浏览器环境下时window对象
- 在nodejs中时global对象
2,声明提升
JavaScript 提升是指解释器在执行代码之前,似乎将函数、变量、类或导入的声明移动到其作用域的顶部的过程。
- 由function声明的函数和var定义的变量,会被进行提升
- 赋值语句的函数不会被提升,如 const foo = function(){}
- var声明的变量被提升后,默认值为undefined,提升时不会赋值
- 函数会首先被提升,然后才是变量
- function*,async function,async function*声明也会被提升
3,作用域
- 作用域是指变量在程序中可访问的区域
- 作用域分为全局作用域,函数作用域,块级作用域
- ES6引入了let和const声明方式,使得JavaScript拥有了块级作用域。块级作用域是指变量或函数仅在它们被声明的块({})内部可见。
- 作用域链是由多个作用域组成的链式结构
- 在查找变量和函数时,会沿着作用域链向上查找,直到全局作用域
- 内部作用域可以访问外部作用域的变量,但外部作用域不能访问内部作用域的变量。
4,预编译
全局预编译
- 创建全局执行上下文GO
- 函数声明提升
- var声明的变量提升,值为undefined
- 运行代码
函数预编译
- 创建执行上下文AO
- 函数内声明的函数和变量提升
- 声明形参
- 实参与形参绑定
- 运行代码
看一道示例题目,输出1,2,2
- 函数内声明和变量提升,所以此时function b和var c被提升
- 声明形参a,b,赋值实参的值1,undefined 所以此时 a=1,b=undefined
- 继续向下执行console.log(a);输出 1
- a被赋值3,b被赋值2 所以后面两个都是输出2
function fn(a,b){
console.log(a);
c =0
var c;
a=3
b=2
console.log(b);
function b(){}
console.log(b);
}
fn(1)
5,调用栈
- 调用栈是一种数据结构,用于跟踪函数的调用顺序和状态。
- 每当一个函数被调用时,其执行上下文会被推入调用栈。
- 当函数执行完毕,其上下文则从栈顶弹出,控制权返回到调用它的上层函数作用域或全局作用域。