《告别var!现代JS变量声明终极指南:let/const的精髓与陷阱》

70 阅读2分钟

var、let、const 学习笔记

概述

  • JavaScript 经历了从 ES5 到 ES6(2015年)的演进,向 Java/C++ 等大型语言靠拢
  • 建议在企业级开发中不再使用 var,改用 letconst

变量声明方式

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;
  • letconst 不会提升,存在暂时性死区,也可以这么说,就是,在代码编译阶段,变量也提升了,不过变量是被放在暂时性死区里,不允许访问,从而达到变量没有提升的效果

块级作用域

{//这个就是块级作用域{}
    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,的提升只是对声明提升到代码顶部,但是函数提升会整体的提升,包括函数的值

常见错误类型

  1. ReferenceError: *** is not defined

    • 在作用域外访问变量
  2. TypeError: Assignment to constant variable

    • const 声明的常量重新赋值
  3. ReferenceError: Cannot access *** before initialization

    • 在暂时性死区内访问 letconst 声明的变量

最佳实践

  1. 默认使用 const,需要重新赋值时使用 let
  2. 避免使用 var
  3. 使用 Object.freeze() 确保对象完全不可变
  4. 利用块级作用域管理变量生命周期