若本文章对您有益,麻烦收藏点赞关注,谢谢!

目录

🟢 一、JS 中的数据类型分类

1. 基本数据类型(Primitive Types)

2. 引用数据类型(Reference Types)

🟢 二、不同类型的检测方法

1. typeof 运算符

2. instanceof 运算符

3. Object.prototype.toString.call()

4. 其它检测方式(特殊情况)

🟢 三、总结对比

👉 面试时推荐回答:

简单封装toString 方法:


🟢 一、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 的类型系统想象成一个大家庭,这个家庭里有两大派系:

  1. 原始类型(Primitive Types):像家里的几个基础成员,性格简单直接,他们的“身体”里存储的就是最原始的值

  2. 引用类型(Reference Types):像一个复杂的组织(比如 Object),这个组织下面有很多分支(如 ArrayFunction 等)。他们的“身体”里存储的是一个“地址”,这个地址指向内存中一个复杂的结构

🟢 二、不同类型的检测方法

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

⚠️ 局限性:

  1. 不能检测基本类型

  2. 受原型链影响,不同执行上下文(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),functionnull 会误判为 object,数组/对象无法区分
instanceof引用类型(Array、Object、Function、Date 等)不能检测基本类型,跨 iframe 可能失效
Object.prototype.toString.call所有类型(最精准)写法稍微繁琐
专门方法Array.isArrayNumber.isNaN适合特定场景

跨 iframe” 其实说的是 一个网页里嵌套了另一个网页(iframe 标签),而两个网页运行在不同的全局环境(不同的执行上下文)

  • iframe:在一个页面中嵌套另一个页面,它们各自有独立的 JS 执行环境。

  • 跨 iframe 问题:同名构造函数(比如 ArrayObject)其实不是同一个引用。

  • 影响instanceof 在跨 iframe 判断类型时可能失效。

  • 解决Object.prototype.toString.call() 来判断更稳妥。

方法示例结果适用场景局限性
typeoftypeof 123"number"检测基本类型、函数null"object",数组/对象区分不了
instanceof[] instanceof Arraytrue判断某个对象是否由构造函数创建跨 iframe 不准确,不能检测基本类型
Object.prototype.toString.callObject.prototype.toString.call([])"[object Array]"最精准,能检测所有类型写法繁琐
Array.isArrayArray.isArray([])true判断数组仅限数组
Number.isNaNNumber.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"

更多推荐