tutorial-basics
标题
✅ 核心结论
- JavaScript 中的数据类型主要分为两大类:基本数据类型(Primitive Types) 和 引用数据类型(Reference Types)。
- 基本数据类型存储在栈(Stack)内存中,其值不可变,变量赋值时是值的拷贝。
- 引用数据类型存储在堆(Heap)内存中,栈中存储的是指向堆中实际对象的地址(引用),其值可变,变量赋值时是引用的拷贝。
- 判断数据类型有多种方法,其中
Object.prototype.toString.call() 是最准确的。
🧠 关键概念
- 基本数据类型 (Primitive Types):
- Number (数值):包含整数和浮点数,特殊值有
NaN、Infinity、-Infinity。 - String (字符串):由单引号、双引号或反引号包裹的字符序列。
- Boolean (布尔值):只有
true 和 false 两个值。 - Undefined (未定义):变量已声明但未赋值时的默认值。
- Null (空值):表示“空”的对象引用。
- Symbol (符号 - ES6 新增):表示唯一的、不可变的值,常用于定义对象的唯一属性名。
- BigInt (任意精度整数 - ES2020 新增):用于表示大于 $2^{53} - 1$ 的整数,通过在数字后加
n 表示(如 100n)。
- 引用数据类型 (Reference Types):
- Object (对象):最基础的引用类型,是键值对的集合。
- Array (数组):一种特殊的对象,用于按顺序存储一组值。
- Function (函数):一种特殊的对象,是可以执行的代码块。
- 其他内置对象:如
Date、RegExp、Map、Set 等。
- 内存存储:
- 栈 (Stack):存储基本数据类型的值。
- 堆 (Heap):存储引用数据类型的实际对象,栈中存储其引用地址。
- 类型判断方法:
typeof 操作符:适用于基础类型,但有缺陷。instanceof 操作符:用于检测构造函数的 prototype 属性是否出现在实例对象的原型链上。Object.prototype.toString.call():最准确的类型识别方法。Array.isArray():专门用于判断是否为数组。
📌 适用场景
- 理解内存管理:区分基本类型和引用类型的存储方式(栈与堆)有助于理解变量赋值和数据操作的底层机制。
- 避免副作用:在处理引用类型时,理解其按引用传递的特性,可以避免因共享引用而导致的意外数据修改。
- 精确类型判断:根据不同的需求选择合适的类型判断方法,例如,使用
Object.prototype.toString.call() 进行全面准确的类型识别,或使用 Array.isArray() 快速判断数组。 - 定义唯一属性:利用
Symbol 类型创建对象的唯一属性名,避免属性名冲突。 - 处理大整数:使用
BigInt 处理超出 Number 类型安全范围的整数计算。
⚠️ 常见误区
typeof null 的结果是 "object":这是一个历史遗留的 Bug,null 实际上是基本数据类型。typeof 无法区分所有引用类型:对于数组、对象、日期等引用类型,typeof 都会返回 "object",无法进行细致区分。- 引用类型赋值是拷贝值:实际上,引用类型赋值是拷贝引用(地址),这意味着两个变量可能指向同一个对象,修改其中一个会影响另一个。
- 基本类型值可变:基本类型的值本身是不可变的,对基本类型变量的重新赋值实际上是创建了一个新值并指向它,而不是修改了原值。
✅ 示例
- BigInt 示例:
100n 表示一个 BigInt 类型的整数。 typeof null 示例:typeof null 返回 "object"。instanceof 示例:arr instanceof Array 用于判断 arr 是否为数组。Object.prototype.toString.call() 示例:Object.prototype.toString.call([]) 返回 "[object Array]",可以准确识别数组类型。