Skip to main content

tutorial-basics


标题

✅ 核心结论

  • JavaScript 中的数据类型主要分为两大类:基本数据类型(Primitive Types)引用数据类型(Reference Types)
  • 基本数据类型存储在栈(Stack)内存中,其值不可变,变量赋值时是值的拷贝。
  • 引用数据类型存储在堆(Heap)内存中,栈中存储的是指向堆中实际对象的地址(引用),其值可变,变量赋值时是引用的拷贝。
  • 判断数据类型有多种方法,其中 Object.prototype.toString.call() 是最准确的。

🧠 关键概念

  • 基本数据类型 (Primitive Types)
    • Number (数值):包含整数和浮点数,特殊值有 NaNInfinity-Infinity
    • String (字符串):由单引号、双引号或反引号包裹的字符序列。
    • Boolean (布尔值):只有 truefalse 两个值。
    • Undefined (未定义):变量已声明但未赋值时的默认值。
    • Null (空值):表示“空”的对象引用。
    • Symbol (符号 - ES6 新增):表示唯一的、不可变的值,常用于定义对象的唯一属性名。
    • BigInt (任意精度整数 - ES2020 新增):用于表示大于 $2^{53} - 1$ 的整数,通过在数字后加 n 表示(如 100n)。
  • 引用数据类型 (Reference Types)
    • Object (对象):最基础的引用类型,是键值对的集合。
    • Array (数组):一种特殊的对象,用于按顺序存储一组值。
    • Function (函数):一种特殊的对象,是可以执行的代码块。
    • 其他内置对象:如 DateRegExpMapSet 等。
  • 内存存储
    • 栈 (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]",可以准确识别数组类型。