js 变量
# 变量
# 变量声明方式
# 1. var
var 命令会发生“变量提升”现象,即变量可以在声明之前使用,值为 undefined
# 2. let
let 不允许在相同作用域
内,重复声明同一个变量。
**暂时性死区**的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。
# 3. const
const 声明一个只读的常量。一旦声明,常量的值就不能改变。
const 的作用域与 let 命令相同:只在声明所在的块级作用域内有效。
const 命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用。
const 声明的常量,也与 let 一样不可重复声明。
const 实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,const 只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。
# let/var/const 区别
- 作用域不同
var:var 声明的变量是所在函数内,没有块级作用域
let/const:let 和 const 声明的变量是所在{}花括号内,且有块级作用域
- 变量提升
var:使用 var 声明的变量存在变量提升,可以先使用后声明
let/const:使用 let 和 const 声明的变量不存在变量提升,且存在暂时性死区
- 值是否能修改
var/let:声明的值可以修改
const:声明的值不可以修改(基本数据类型不能修改值,引用数据类型不能修改地址,即不能重新整体赋值)
# 声明提升
函数声明提升的优先级是高于变量声明的
这里的优先级指的是:同名的变量和函数中,函数先提升,再遇到同名的变量或函数,提升都将被编译器忽略。
JavaScript 中,函数及变量的声明都将被提升到函数的最顶部。
JavaScript 中,变量可以在使用后声明,也就是变量可以先使用再声明。
JavaScript 只有声明的变量会提升,初始化的不会。
# 变量提升和函数声明提升
注意点:JavaScript 严格模式(strict mode)不允许使用未声明的变量。
变量的声明和函数的声明提升,提升的时机发生在预解析过程中。
预解析过程也就是创建 AO(Activation Object) 的过程。
创建 AO 过程:
创建 AO 对象。
将形参和函数内变量声明作为对象的属性名,属性值统一为 undefined。
将实参赋值给形参。
找函数内的函数声明作为对象的属性名,属性值为函数体。
# 变量提升
原则上变量应该先声明后使用,但是程序员小白常常忘记声明就使用了变量,这样做 js 代码在执行的时候不报错,只是返回了一个 undefined。这种情况就是变量提升。
计算机执行的时候会把未声明就使用的变量隐式的放到代码的最顶端。需要注意的是变量虽然发生了提升,但是给变量赋的值是不会随之提升的,所以就会得到结果 undefined。
# 函数提升
与变量提升的意思差不多,先使用函数,后再声明函数,这种违背逻辑的事情在 JavaScript 中是允许的,这门语言就是这么灵活。
与变量提升不同的是,函数的返回值也会随之提升,所以你会发现在 script 标签中的任何地方都能调用函数并且使用函数的返回值。