var、let、const 学习笔记
概述
- JavaScript 经历了从 ES5 到 ES6(2015年)的演进,向 Java/C++ 等大型语言靠拢
- 建议在企业级开发中不再使用
var,改用let和const
变量声明方式
var(ES5)
var age = 18;
age++;
特点:
- 存在变量提升(hoisting)
- 不支持块级作用域(不受{}这个块的束缚)
- 被认为是语言的"糟粕"部分
let(ES6)
let height = 188;
height++;
特点:
- 不存在变量提升
- 支持块级作用域
- 有暂时性死区(Temporal Dead Zone)
const(ES6)
const key = 'abc123';
// key = '123'; // 会报错
特点:
- 声明常量,不可重新赋值,变量名称不允许重复
- 支持块级作用域
- 有暂时性死区
关键概念
变量提升(Hoisting)
console.log(age); // undefined
var age = 18;
console.log(PI); // ReferenceError
const PI = 3.14;
var声明的变量会提升,在代码编译时,就到达代码的顶部,实际上的代码是下面这个,,声明了变量age但是没有给age赋值,所以是undefined
var age;
console.log(age); // undefined
age = 18;
let和const不会提升,存在暂时性死区,也可以这么说,就是,在代码编译阶段,变量也提升了,不过变量是被放在暂时性死区里,不允许访问,从而达到变量没有提升的效果
块级作用域
{//这个就是块级作用域{}
var age = 18;
let age1 = 0;
const age2 = 0;
}
console.log(age); // 18
console.log(age1); // ReferenceError
console.log(age2); // ReferenceError
常量与对象
const person = {
name: 'yang',
age: 18
};
person.name = '哈哈哈'; // 允许,修改属性值
// person = {}; // 报错,不能改变引用地址
- 可以修改常数的属性值,但是不能修改其本身
// 完全冻结对象
const wes = Object.freeze(person);
wes.age = 0; // 静默失败,不会改变
- 使用
Object.freeze(person)方法来冻结对象,这样就无法修改其属性值
函数提升
swtWidth(); // 可以正常调用
function swtWidth(){
var width = 100;
console.log(width);
}
- 函数声明会整体提升(包括函数体)
- 与
var只提升声明不同,var,的提升只是对声明提升到代码顶部,但是函数提升会整体的提升,包括函数的值
常见错误类型
-
ReferenceError: *** is not defined
- 在作用域外访问变量
-
TypeError: Assignment to constant variable
- 给
const声明的常量重新赋值
- 给
-
ReferenceError: Cannot access *** before initialization
- 在暂时性死区内访问
let或const声明的变量
- 在暂时性死区内访问
最佳实践
- 默认使用
const,需要重新赋值时使用let - 避免使用
var - 使用
Object.freeze()确保对象完全不可变 - 利用块级作用域管理变量生命周期