知识篇 -- JS变量与数据类型

Ray Shine 2024/1/25 JavaScript基础知识

在JavaScript编程中,变量是存储数据的容器,而数据类型则定义了这些数据可以表示的值的种类。理解变量的声明方式及其背后的机制,以及JavaScript的各种数据类型,是编写有效、健壮代码的第一步。

# 一、变量:数据的容器 核心

变量允许我们给数据一个名字,方便在程序中引用和操作这些数据。JavaScript提供了三种声明变量的方式:varletconst

# 1. var:老旧的声明方式 (ES5及之前) 不推荐

  • 特点
    • 函数作用域var 声明的变量只在函数内部有效,在函数外部无法访问。如果在函数外部声明,则为全局变量。
    • 变量提升 (Hoisting)var 声明的变量会被提升到其所在作用域的顶部,但赋值操作不会被提升。这意味着你可以在声明之前使用 var 变量,但其值为 undefined
    • 可重复声明:在同一个作用域内,可以重复声明同名 var 变量,后面的声明会覆盖前面的。
  • 示例
    console.log(a); // undefined (变量提升)
    var a = 10;
    console.log(a); // 10
    
    function testVar() {
        var b = 20;
        console.log(b); // 20
        var b = 30; // 可重复声明
        console.log(b); // 30
    }
    testVar();
    // console.log(b); // ReferenceError: b is not defined (函数作用域)
    
  • 缺点var 的这些特性(尤其是变量提升和可重复声明)容易导致意外的错误和代码难以维护,因此在现代JavaScript开发中,推荐使用 letconst

# 2. let:块级作用域的变量 (ES6新增) 推荐

  • 特点
    • 块级作用域let 声明的变量只在当前代码块({} 内部)有效。
    • 无变量提升let 变量不会被提升,在声明之前使用会报错(暂时性死区)。
    • 不可重复声明:在同一个块级作用域内,不允许重复声明同名 let 变量。
  • 示例
    // console.log(x); // ReferenceError: Cannot access 'x' before initialization (暂时性死区)
    let x = 10;
    console.log(x); // 10
    
    if (true) {
        let y = 20;
        console.log(y); // 20
        // let y = 30; // SyntaxError: Identifier 'y' has already been declared
    }
    // console.log(y); // ReferenceError: y is not defined (块级作用域)
    
  • 优点let 解决了 var 的许多问题,使得变量管理更加严谨和可控。

# 3. const:常量 (ES6新增) 推荐

  • 特点
    • 块级作用域:与 let 相同,具有块级作用域。
    • 无变量提升:与 let 相同,存在暂时性死区。
    • 不可重复声明:与 let 相同,不允许重复声明。
    • 声明时必须初始化const 声明的变量必须在声明时赋值。
    • 赋值后不可再修改:一旦赋值,就不能再重新赋值。
  • 示例
    const PI = 3.14;
    // PI = 3.14159; // TypeError: Assignment to constant variable.
    
    const obj = { name: "Alice" };
    obj.name = "Bob"; // 对象的属性可以修改
    // obj = { name: "Charlie" }; // TypeError: Assignment to constant variable.
    
  • 注意const 保证的是变量指向的那个内存地址不能改变,而不是变量的值不能改变。对于基本数据类型,值存储在变量指向的地址,所以值不能变。对于引用数据类型(如对象、数组),变量指向的是内存地址,该地址不能变,但地址中存储的对象内容是可以修改的。

# 二、数据类型:数据的分类 基础

JavaScript中的数据类型分为两大类:基本数据类型 (Primitive Types)引用数据类型 (Reference Types)

# 1. 基本数据类型 (Primitive Types) 不可变

基本数据类型的值直接存储在变量访问的位置,它们是不可变的(immutable),即一旦创建就不能被修改。

  • String (字符串):表示文本数据。
    • 示例"Hello World", 'JavaScript', `Template Literal`
  • Number (数字):表示整数或浮点数。
    • 示例10, 3.14, -5, NaN (Not a Number), Infinity
  • Boolean (布尔值):表示逻辑实体,只有两个值:truefalse
    • 示例true, false
  • Null (空值):表示一个空对象指针,只有一个值 null
    • 示例null
  • Undefined (未定义):表示变量已声明但未赋值,只有一个值 undefined
    • 示例let x; console.log(x); // undefined
  • Symbol (符号) (ES6新增):表示独一无二的值,主要用于对象的属性键。
    • 示例const sym = Symbol('description');
  • BigInt (大整数) (ES2020新增):表示任意精度的整数。
    • 示例10n, BigInt(100)

# 2. 引用数据类型 (Reference Types) 可变

引用数据类型的值存储在堆内存中,变量存储的是指向这些值的内存地址。它们是可变的(mutable),可以通过引用来修改其内容。

  • Object (对象):表示键值对的集合,是JavaScript中最基本也是最重要的引用类型。
    • 示例{ name: "Alice", age: 30 }
  • Array (数组):表示有序的元素集合,是特殊的对象。
    • 示例[1, 2, 3], ["apple", "banana"]
  • Function (函数):表示可执行的代码块,也是特殊的对象。
    • 示例function greet() { /* ... */ }
  • Date (日期):表示日期和时间。
  • RegExp (正则表达式):表示正则表达式。

基本数据类型与引用数据类型的区别: 重要

特性 基本数据类型 引用数据类型
存储方式 直接存储在栈内存中 存储在堆内存中,栈内存中存储的是指向堆内存的地址
赋值方式 值复制:赋值后两个变量互不影响 引用复制:赋值后两个变量指向同一个对象,一个改变另一个也改变
比较方式 值比较:只有值相等才相等 引用比较:只有指向同一个内存地址才相等
可变性 不可变:值一旦创建就不能被修改 可变:可以通过引用修改其内容

示例:

// 基本数据类型赋值
let num1 = 10;
let num2 = num1;
num2 = 20;
console.log(num1); // 10
console.log(num2); // 20

// 引用数据类型赋值
let obj1 = { value: 10 };
let obj2 = obj1;
obj2.value = 20;
console.log(obj1.value); // 20
console.log(obj2.value); // 20

理解JavaScript的变量声明方式和数据类型是掌握这门语言的基础。合理选择 varletconst,并区分基本类型和引用类型,能帮助你写出更清晰、更少bug的代码。

最后更新时间: 2025/11/20 22:59:30
ON THIS PAGE