JavaScript 数据类型与检测方法
JavaScript 基本类型、引用类型及四种类型检测方式
问题
JavaScript 有哪些数据类型?如何检测数据类型?
解答
数据类型
基本类型(7 种):undefined、null、boolean、number、string、symbol、bigint
引用类型:Object(包括 Array、Function、Date、RegExp、Error 等)
检测方法
1. typeof
// 基本类型
typeof undefined // "undefined"
typeof true // "boolean"
typeof 123 // "number"
typeof "abc" // "string"
typeof Symbol() // "symbol"
typeof 123n // "bigint"
// 特殊情况
typeof null // "object" (历史遗留 bug)
typeof function(){} // "function"
typeof [] // "object"
typeof {} // "object"
2. instanceof
// 检测引用类型,基于原型链
[] instanceof Array // true
[] instanceof Object // true
({}) instanceof Object // true
// 无法检测基本类型
"abc" instanceof String // false
123 instanceof Number // false
// 手动实现 instanceof
function myInstanceof(obj, constructor) {
let proto = Object.getPrototypeOf(obj);
while (proto !== null) {
if (proto === constructor.prototype) return true;
proto = Object.getPrototypeOf(proto);
}
return false;
}
3. constructor
// 通过构造函数判断
(123).constructor === Number // true
"abc".constructor === String // true
[].constructor === Array // true
// 缺点:constructor 可被修改
function Person() {}
const p = new Person();
p.constructor = Array;
p.constructor === Array // true (已被篡改)
// null 和 undefined 没有 constructor
// null.constructor // TypeError
4. Object.prototype.toString.call
// 最准确的检测方法
Object.prototype.toString.call(undefined) // "[object Undefined]"
Object.prototype.toString.call(null) // "[object Null]"
Object.prototype.toString.call(true) // "[object Boolean]"
Object.prototype.toString.call(123) // "[object Number]"
Object.prototype.toString.call("abc") // "[object String]"
Object.prototype.toString.call(Symbol()) // "[object Symbol]"
Object.prototype.toString.call(123n) // "[object BigInt]"
Object.prototype.toString.call([]) // "[object Array]"
Object.prototype.toString.call({}) // "[object Object]"
Object.prototype.toString.call(function(){})// "[object Function]"
Object.prototype.toString.call(new Date()) // "[object Date]"
Object.prototype.toString.call(/abc/) // "[object RegExp]"
// 封装通用检测函数
function getType(value) {
return Object.prototype.toString.call(value).slice(8, -1).toLowerCase();
}
getType(null) // "null"
getType([]) // "array"
getType(new Date()) // "date"
方法对比
| 方法 | 优点 | 缺点 |
|---|---|---|
| typeof | 简单快速 | null 返回 “object”,无法区分引用类型 |
| instanceof | 能检测具体引用类型 | 不能检测基本类型,跨 iframe 失效 |
| constructor | 能检测基本类型和引用类型 | 可被修改,null/undefined 报错 |
| toString | 最准确,能检测所有类型 | 写法较长 |
关键点
- 基本类型 7 种,引用类型本质都是 Object
typeof null === "object"是历史 buginstanceof基于原型链,只能检测引用类型Object.prototype.toString.call是最可靠的检测方式- 实际开发中常封装
getType工具函数
目录