预编译
- js是解释性语言,主要特点为解释一行执行一行,而在js运行时会进行三件事:
- 语法分析:检查错误
- 预编译:对整个代码进行一次“初步编译”
- 解释执行:执行代码
- 预编译分为:全局和局部
全局预编译
- 创建
GO
全局对象 - 查找==
var
声明的变量==,将其变量名作为GO
属性名,值为undefined
(变量提升) - 查找声明式函数,将函数名作为
GO
属性名,值为函数体(函数提升)
局部预编译
- 创建
AO
对象 - 查找函数的形参和==
var
声明的变量==,将其变量名作为AO
属性名,值为undefined
(变量提升) - 查找声明式函数,将函数名作为
AO
属性名,值为函数体(函数提升) - 查找函数调用的传参,覆盖掉形参的undefined
变量
-
ECMAScript 变量是松散类型的,变量可以用于保存任何类型的数据
-
变量声明不开辟空间,变量赋值才开辟空间
-
变量只赋值不声明,则自动声明为全局变量(不推荐)
- 变量只声明不赋值,使用时值为
undefined
- 变量只声明不赋值,使用时值为
-
let a=b=1;
相当于let a=1;b=1;
-
let a=1,b=1;
相当于let a=1; let b=1;
(推荐)
var
- 存在变量提升
- 只识别函数的
{}
,if,for等不识别{}
,都会暴露 - 允许重复赋值
- 在全局上下文环境中声明,会变成全局变量
let
-
let
声明的变量不存在变量提升,也叫暂时性死区(在声明前使用该变量就报错) -
识别任何
{}
-
重复赋值就报错:同一作用域内不允许重复声明,就算使用var也会报错
- 因为js会记录该变量声明和其所在的块级上下文,用于判断重名
let rs=10; var rs=34;//报错,重名就报错
-
在全局声明,不会定义在全局上下文中,但作用域链效果一样
const(推荐)
- 使用
const
声明变量时必须同时初始化变量 - 修改
const
声明的变量会报错- 原理:指向的地址不变(所以对象可以更改)
- 解决:使用
Object.freeze()
冻结变量
- 其他与
let
基本相同