Appearance
JavaScript 数据类型详解
数据类型种类
TIP
JavaScript 中有 8 种数据类型
- 七种基本数据类型
StringNumberBooleanNullUndefinedSymbolBigInt - 一种引用类型
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 区别
| 特性 | null | undefined |
|---|---|---|
| 含义 | 空对象指针 | 未初始化的值 |
| 类型 | object | undefined |
| 数值转换 | 转换为 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 对比
| 特性 | var | let | const |
|---|---|---|---|
| 作用域 | 函数作用域 | 块级作用域 | 块级作用域 |
| 重复声明 | ✓ 允许 | ✗ 禁止 | ✗ 禁止 |
| 变量提升 | ✓ 存在 | ✗ 不存在 | ✗ 不存在 |
| 全局属性 | 成为 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 规则详解
- 进入块作用域时立即创建 TDZ
- 执行到声明语句时才初始化变量
- 访问 TDZ 变量抛出
ReferenceError typeof检测 TDZ 变量也会报错
js
{
// TDZ开始
typeof tmp; // ❌ ReferenceError
let tmp; // TDZ结束
console.log(tmp); // undefined
}