JavaScript 数据类型有哪些?怎么检测?
若本文章对您有益,麻烦收藏点赞关注,谢谢!
目录
3. Object.prototype.toString.call()
🟢 一、JS 中的数据类型分类
JavaScript 一共分为两大类:
1. 基本数据类型(Primitive Types)
-
Number(数字) -
String(字符串) -
Boolean(布尔值,true/false) -
Undefined(未定义) -
Null(空对象指针) -
Symbol(唯一值,ES6 新增) -
BigInt(任意大整数,ES2020 新增)
👉 特点:不可变、存储在栈内存。
2. 引用数据类型(Reference Types)
-
Object(对象,最基础的引用类型)-
普通对象:
{} -
数组:
[] -
函数:
function -
日期:
Date -
正则:
RegExp -
Map、Set、WeakMap、WeakSet 等(ES6 新增)
-
👉 特点:可变、存储在堆内存,变量存的是引用地址。
你可以把 JavaScript 的类型系统想象成一个大家庭,这个家庭里有两大派系:
-
原始类型(Primitive Types):像家里的几个基础成员,性格简单直接,他们的“身体”里存储的就是最原始的值。
-
引用类型(Reference Types):像一个复杂的组织(比如
Object),这个组织下面有很多分支(如Array,Function等)。他们的“身体”里存储的是一个“地址”,这个地址指向内存中一个复杂的结构。
🟢 二、不同类型的检测方法
1. typeof 运算符
适合检测:基本类型
typeof 123 // "number"
typeof "hello" // "string"
typeof true // "boolean"
typeof undefined // "undefined"
typeof Symbol() // "symbol"
typeof 10n // "bigint"
typeof function(){} // "function"
⚠️ 注意坑点:
typeof null // "object" (历史遗留 bug)
typeof [] // "object"
typeof {} // "object"
👉 所以 typeof 不能区分 null、数组、对象。
2. instanceof 运算符
适合检测:对象类型(引用类型)
[] instanceof Array // true
{} instanceof Object // true
new Date() instanceof Date // true
function(){} instanceof Function // true
⚠️ 局限性:
-
不能检测基本类型
-
受原型链影响,不同执行上下文(iframe)下可能不准。
3. Object.prototype.toString.call()
👉 最精准、通用的方法(几乎可以检测所有类型)。
Object.prototype.toString.call(123) // "[object Number]"
Object.prototype.toString.call("hi") // "[object String]"
Object.prototype.toString.call(true) // "[object Boolean]"
Object.prototype.toString.call(null) // "[object Null]"
Object.prototype.toString.call(undefined) // "[object Undefined]"
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([]) // "array"
getType(null) // "null"
getType(123) // "number"
4. 其它检测方式(特殊情况)
-
Array.isArray([])→ 判断是否为数组 -
isNaN(value)→ 判断是否为 NaN(但推荐Number.isNaN更精确) -
Number.isInteger(10)→ 判断是否为整数 -
value.constructor === Array→ 判断构造函数(不推荐,容易被修改
🟢 三、总结对比
| 方法 | 能检测哪些 | 局限性 |
|---|---|---|
typeof | 基本类型(number/string/boolean/undefined/symbol/bigint),function | null 会误判为 object,数组/对象无法区分 |
instanceof | 引用类型(Array、Object、Function、Date 等) | 不能检测基本类型,跨 iframe 可能失效 |
Object.prototype.toString.call | 所有类型(最精准) | 写法稍微繁琐 |
| 专门方法 | Array.isArray、Number.isNaN 等 | 适合特定场景 |
“跨 iframe” 其实说的是 一个网页里嵌套了另一个网页(iframe 标签),而两个网页运行在不同的全局环境(不同的执行上下文)。
-
iframe:在一个页面中嵌套另一个页面,它们各自有独立的 JS 执行环境。
-
跨 iframe 问题:同名构造函数(比如
Array、Object)其实不是同一个引用。 -
影响:
instanceof在跨 iframe 判断类型时可能失效。 -
解决:用
Object.prototype.toString.call()来判断更稳妥。
| 方法 | 示例 | 结果 | 适用场景 | 局限性 |
|---|---|---|---|---|
| typeof | typeof 123 | "number" | 检测基本类型、函数 | null → "object",数组/对象区分不了 |
| instanceof | [] instanceof Array | true | 判断某个对象是否由构造函数创建 | 跨 iframe 不准确,不能检测基本类型 |
| Object.prototype.toString.call | Object.prototype.toString.call([]) | "[object Array]" | 最精准,能检测所有类型 | 写法繁琐 |
| Array.isArray | Array.isArray([]) | true | 判断数组 | 仅限数组 |
| Number.isNaN | Number.isNaN(NaN) | true | 判断 NaN | 不会像 isNaN("a") 那样误判 |
👉 面试时推荐回答:
“JS 数据类型有 7 种基本类型和多种引用类型。常见检测方式有:typeof(适合基本类型)、instanceof(适合对象)、Object.prototype.toString.call(最精准)、以及专门方法如 Array.isArray。实际开发中一般封装 toString 方法做统一判断。”
简单封装toString 方法:
function getType(value) {
return Object.prototype.toString.call(value).slice(8, -1).toLowerCase();
}
使用:
getType(123); // "number"
getType("hello"); // "string"
getType(null); // "null"
getType(undefined); // "undefined"
getType([]); // "array"
getType({}); // "object"
getType(new Date()); // "date"
getType(/abc/); // "regexp"
更多推荐
所有评论(0)