变量声明
var
-
函数作用域
-
存在变量提升(声明提升)
-
能够重复定义(在变量提升时被合并)
为什么不推荐使用var
-
声明提升:变量使用在变量声明初始化之前,程序正常运行,但其值为undefined,对实际结果产生影响
-
能重复定义,导致变量声明覆盖
-
没有局部作用域(块级作用域),会导致变量外泄
let
-
块级作用域
-
不存在声明提升(原因:暂时性死区)
-
不能重复定义
const
-
const声明后必须赋值
-
const定义变量不能被更改,引用类型会被更改
其他
-
未声明就使用的变量---全局变量
-
在全局作用域下使用var定义的变量会变成window对象上的变量,let声明的变量不会
预编译
在 JS 运行之前,会经历 JS 的预编译过程,预编译的时候会涉及到 2 个对象,分别是:
- GO 对象全称为 global object(全局对象,等同于window)
- AO 对象全称为:activation object (活跃对象/执行期上下文)
GO 对象
在开始预编译时产生的对象,比 AO 对象先产生,用于存放全局变量,也称为全局作用域。
GO 预编译三步骤:
- 生成 GO 对象
- 将变量声明的变量名当做 GO 对象的属性名,值为
undefined - 将声明函数的函数名当做 GO 对象的属性名,值为函数体
AO 对象
AO 预编译三步骤:
- 创建Activation Object,即:AO对象
- 找形参和变量声明,将变量声明和形参作为AO的属性名,值为underfined;
- 将实参和形参值统一;
- 在函数体里找函数声明,将函数名作为AO对象的属性名,值赋予函数体。