Skip to content

JavaScript 数据类型详解

温馨提示:本内容整理自阅读 《JavaScript 权威指南(第 7 版)》 和社区大神文章。

JavaScript 的数据类型分为:基本数据类型引用数据类型

📌 基本数据类型(原始类型)

在 ES2020 标准中,共有 7 种基本类型:

  • undefined:未定义
  • null:空指针
  • boolean:布尔值
  • string:字符串
  • number:数值
  • symbol:独一无二的值(ES6 引入)
  • bigint:大整数(ES2020 引入)

✅ 特性总结

  • 保存原始值,无属性和方法
  • 存储在 栈内存
  • 通过 按值访问
  • 复制时创建副本,互不影响

❓ 原始值能用方法?

js
const str = 'hello world';
str.toString();  // ✅
str.length;      // ✅

其实是 JavaScript 内部做了包装处理:

js
const str = 'hello world';
new String(str).toString();
new String(str).length;

背后执行了:

  1. 创建对应包装类实例(如 String
  2. 调用方法/属性
  3. 销毁临时对象

📦 引用数据类型

除了基本类型,其他的都是引用类型:

  • Object:普通对象
  • Array:数组
  • Function:函数
  • Date:时间对象
  • RegExp:正则表达式
  • Set / WeakSet(ES6)
  • Map / WeakMap(ES6)

✅ 特性总结

  • 保存对象地址(引用),本体在堆内存
  • 通过 按引用访问
  • 复制的是地址(多个变量指向同一个对象)

🧠 栈内存 vs 堆内存

类型描述
栈内存存储变量和地址,内存空间连续,速度快
堆内存存储引用对象和闭包变量,内存不连续

📚 延伸阅读:JS 中的栈内存和堆内存

🔍 类型判断方式(五种)

1️⃣ typeof

js
typeof undefined        // 'undefined'
typeof null             // 'object' ❗️
typeof true             // 'boolean'
typeof 'hi'             // 'string'
typeof 123              // 'number'
typeof Symbol()         // 'symbol'
typeof BigInt(10)       // 'bigint'

❓ 为什么 typeof null === 'object'

null 本是空指针(0x00),JS 最初实现中对象的类型标签是 0,因此错误地识别为 object —— MDN 解释

引用类型结果:

js
typeof {}               // 'object'
typeof []               // 'object'
typeof () => {}         // 'function'

2️⃣ instanceof

判断某对象是否是某构造函数的实例(原型链上是否存在)

js
const arr = [];
arr instanceof Array         // true
arr instanceof Object        // true

'hi' instanceof String       // false ❗️
true instanceof Boolean      // false ❗️

改变原型影响判断:

js
function Person(name) {
  this.name = name;
}
const p = new Person('Tom');

Reflect.setPrototypeOf(p, Array.prototype);
p instanceof Person  // false
p instanceof Array   // true

结论

  • 仅适合判断引用类型
  • 构造函数原型被改动后判断结果不准确

3️⃣ constructor

使用 .constructor 判断构造函数:

js
(true).constructor === Boolean      // true
'hi'.constructor === String         // true
(123).constructor === Number        // true

({}).constructor === Object         // true
[].constructor === Array            // true
js
function Person() {}
Person.prototype = {};
(new Person()).constructor === Object  // true ❗️

结论

  • 不能判断 nullundefined
  • 构造函数原型被改动会导致错误

4️⃣ Array.isArray()

专用于判断是否为数组:

js
Array.isArray([]);     // true
Array.isArray({});     // false

✅ 推荐使用!

5️⃣ Object.prototype.toString

最强通用类型判断法:

js
const toString = Object.prototype.toString;

toString.call(undefined)    // '[object Undefined]'
toString.call(null)         // '[object Null]'
toString.call(true)         // '[object Boolean]'
toString.call('hi')         // '[object String]'
toString.call(123)          // '[object Number]'
toString.call(Symbol())     // '[object Symbol]'
toString.call(BigInt(10))   // '[object BigInt]'

toString.call([])           // '[object Array]'
toString.call({})           // '[object Object]'
toString.call(() => {})     // '[object Function]'
toString.call(new Date())   // '[object Date]'

📖 Object.prototype.toStringECMAScript 5 中的大致流程:

  1. 如果是 undefinednull,直接返回结果
  2. 将值转为对象 O = ToObject(this)
  3. 获取其内部 [[Class]]
  4. 返回格式为 [object Type]

✅ 总结

类型判断方法优点缺点
typeof判断基本类型快无法识别 null 和具体对象
instanceof判断引用类型有效原型被改动就无效
constructor简洁原型被重写时不准
Array.isArray()最好判断数组方式仅限数组
Object.prototype.toString✅最准确通用写法稍繁琐