Skip to content

JavaScript 数据类型详解

数据类型种类

TIP

JavaScript 中有 8 种数据类型

  • 七种基本数据类型
    Boolean Null Undefined Number String Symbol BigInt
  • 一种引用类型
    Object(包含多种形式):
    • 普通对象:{}
    • 数组:[]
    • 正则表达式:/^$/
    • 日期对象:new Date()
    • 数学对象:Math
    • 函数:function() {}

typeof 关键字

  • typeof 操作符总是返回字符串类型的值
  • 检测结果示例:
js
typeof a; // "undefined" (未声明变量)
typeof 1; // "number"
typeof NaN; // "number" (特殊数值)
typeof "zhufeng"; // "string"
typeof true; // "boolean"
typeof Symbol("a"); // "symbol"
typeof function () {}; // "function"
typeof [1, 2, 3]; // "object" (数组)
typeof { name: "zhufeng" }; // "object" (普通对象)
typeof new Number(1); // "object" (包装对象)
typeof null; // "object" (历史遗留问题)

typeof null 等于 object 的原因

js
typeof null; // "object"
  • 历史遗留问题:JavaScript 早期设计中的类型标签机制导致
  • 无法修复:修复会破坏大量现有程序和库的兼容性
  • 正确检测方法
    js
    const isNull = (value) => value === null;

null 和 undefined 区别

特性nullundefined
含义空对象指针未初始化的值
类型objectundefined
数值转换转换为 0 (+null → 0)转换为 NaN (+undefined → NaN)
使用场景主动赋空值变量声明未赋值
js
// 使用场景
var a; // undefined (未初始化)
var b = null; // null (显式赋空值)

// 数值转换差异
console.log(10 + null); // 10 (null → 0)
console.log(10 + undefined); // NaN (undefined → NaN)

引用类型特性

核心特性

引用类型变量存储的是内存地址引用而非实际值,多个变量引用同一对象时,修改会相互影响

js
// 引用类型示例
let person = { username: "hulei" };
let employee = person;

employee.age = 20; // 通过引用修改对象

console.log(person); // {username: "hulei", age: 20}
console.log(employee === person); // true (相同引用)

引用类型内存示意图

内存管理机制

内存区域对比

特性栈 (Stack)堆 (Heap)
结构线性有序存储非线性动态分配
访问速度高速访问相对较慢
存储内容基本类型值/对象引用指针对象实际数据
生命周期随函数执行结束自动释放由垃圾回收机制管理

存储规则

  • 基本类型:值直接存储在栈内存中
  • 引用类型:对象数据存储在堆中,栈中存储指向堆内存的指针
js
// 基本类型 - 栈存储
let num = 10; // 值直接存储在栈中

// 引用类型 - 堆存储
let obj = { value: 10 }; // 对象存储在堆中,栈中存储引用地址

var, let, const 对比

特性varletconst
作用域函数作用域块级作用域块级作用域
重复声明✓ 允许✗ 禁止✗ 禁止
变量提升✓ 存在✗ 不存在✗ 不存在
全局属性成为 window 属性不成为不成为
重新赋值✓ 允许✓ 允许✗ 禁止(对象属性可修改)
js
// var 的典型问题
for (var i = 0; i <= 5; i++) {
  console.log(i);
}
console.log(i); // 6 (变量泄漏到全局)

// let/const 的块级作用域解决方案
for (let j = 0; j <= 5; j++) {
  console.log(j);
}
console.log(j); // ReferenceError: j未定义

暂时性死区 (TDZ)

核心概念

  • 定义:从代码块开始变量声明完成之间的区域
  • 表现:此区域内访问变量会抛出 ReferenceError
  • 机制:变量在声明语句执行时才被初始化
js
// var 允许声明前访问
console.log(a); // undefined
var a = 10;

// let/const 存在暂时性死区
{
  console.log(b); // ReferenceError: 无法在初始化前访问b
  let b = 20;
}

TDZ 规则详解

  1. 进入块作用域时立即创建 TDZ
  2. 执行到声明语句时才初始化变量
  3. 访问 TDZ 变量抛出 ReferenceError
  4. typeof 检测 TDZ 变量也会报错
js
{
  // TDZ开始
  typeof tmp; // ❌ ReferenceError

  let tmp; // TDZ结束
  console.log(tmp); // undefined
}