|
主题设置

卡片式面板通常用于非白色背景色的主体内

JS 变量作用域

在 JavaScript 中,var、let、const 和无声明符(implicit declaration)声明变量的方式有一些区别,主要涉及到作用域和变量提升(hoisting)的处理。

var 声明

var x = 10;
  • 作用域: var 声明的变量作用域是函数作用域或全局作用域(全局作用域下定义的变量会成为全局对象的属性)。
  • 变量提升: 使用 var 声明的变量会在其声明所在的函数或全局作用域的顶部进行变量提升,即在代码执行前就可以访问到变量,但其赋值不会提升:
    console.log(x); // undefined
    var x = 10;
    console.log(x); // 10

上述代码在使用 var 声明的情况下,变量 x 会被提升到代码的顶部,但其赋值部分不会提升,因此第一个 console.log(x) 输出 undefined。

let 声明

let y = 20;
  • 作用域: let 声明的变量作用域是块级作用域(如 { ... } 内部),包括 if、for、while 等语句块。
  • 变量提升: 使用 let 声明的变量在初始化之前访问会造成暂时性死区(Temporal Dead Zone, TDZ),即在声明之前访问会抛出 ReferenceError:
    console.log(y); // ReferenceError: y is not defined
    let y = 20;
    console.log(y); // 20

在上述代码中,使用 let 声明的变量 y 在声明之前访问会抛出 ReferenceError,因为它不会被提升到作用域顶部。

const 声明

const name = value;
  • 声明类型:const 用来声明常量,在声明时必须同时进行初始化赋值,不可重新赋值。
  • 作用域:与 let 类似,const 声明的常量也具有块级作用域,即只在声明所在的块内有效。
  • 变量提升:使用 const 声明的常量在初始化之前访问也会造成暂时性死区(Temporal Dead Zone, TDZ),即在声明之前访问会抛出 ReferenceError:
    console.log(y); // ReferenceError: Cannot access 'y' before initialization
    const y = 20;
  • 对象引用不可变性:使用 const 声明的常量本身不能被修改,但如果常量是一个对象,对象的属性值是可以修改的:
    const person = {
    	name: 'John',
    	age: 30
    };
    person.age = 31; // 可行,因为修改的是对象的属性值,而非常量本身
    person = {}; // 不可行: Assignment to constant variable.

无声明符 声明

z = 30;
  • 作用域: 如果直接给变量赋值而没有使用 var、let 或 const 进行声明,这个变量会被默认添加到全局对象(window 对象浏览器环境下)中,因此在整个代码中都可以访问到。
    console.log(window.z); // 30

在上述代码中,变量 z 被隐式地声明为全局变量,可以通过 window.z 或直接 z 来访问它。

总结

  • 使用 var 声明的变量存在变量提升,作用域是函数作用域或全局作用域。
  • 使用 let 声明的变量也有变量提升,但在声明之前访问会抛出 ReferenceError,作用域是块级作用域。
  • 未经声明直接赋值的变量会被默认添加到全局对象中,全局可访问。

在现代 JavaScript 中,推荐使用 let 和 const 来代替 var,因为它们提供了更好的作用域控制和不可变性保证。