主题
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;
背后执行了:
- 创建对应包装类实例(如
String
) - 调用方法/属性
- 销毁临时对象
📦 引用数据类型
除了基本类型,其他的都是引用类型:
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 ❗️
✅ 结论:
- 不能判断
null
和undefined
- 构造函数原型被改动会导致错误
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.toString
在 ECMAScript 5 中的大致流程:
- 如果是
undefined
或null
,直接返回结果 - 将值转为对象
O = ToObject(this)
- 获取其内部
[[Class]]
- 返回格式为
[object Type]
✅ 总结
类型判断方法 | 优点 | 缺点 |
---|---|---|
typeof | 判断基本类型快 | 无法识别 null 和具体对象 |
instanceof | 判断引用类型有效 | 原型被改动就无效 |
constructor | 简洁 | 原型被重写时不准 |
Array.isArray() | 最好判断数组方式 | 仅限数组 |
Object.prototype.toString | ✅最准确通用 | 写法稍繁琐 |