判断js数据类型

211 阅读3分钟

一、JavaScript 数据类型分类

首先明确 JS 的 7 种基本数据类型和 1 种引用数据类型:

  • 基本类型NumberStringBooleanNullUndefinedSymbol(ES6+)、BigInt(ES10+)。
  • 引用类型Object(包括 ArrayFunctionDateRegExp 等,本质都是对象的子类型)。

二、常用判断方法及适用场景

不同方法有各自的优缺点,需根据场景选择:

1. typeof 运算符(基础但有局限)
  • 语法typeof 变量
  • 返回值:字符串(如 'number''string''object' 等)。
  • 适用场景:判断基本类型(除 Null 外)和 Function
typeof 123;         // 'number'(正确)
typeof 'abc';       // 'string'(正确)
typeof true;        // 'boolean'(正确)
typeof undefined;   // 'undefined'(正确)
typeof Symbol();    // 'symbol'(正确)
typeof 123n;        // 'bigint'(正确)
typeof function(){};// 'function'(正确,特殊处理)

// 局限性
typeof null;        // 'object'(历史bug,错误)
typeof [];          // 'object'(引用类型均返回'object')
typeof {};          // 'object'
2. instanceof 运算符(判断引用类型)
  • 原理:检测构造函数的 prototype 是否在实例对象的原型链上。
  • 适用场景:判断具体的引用类型(如 ArrayDate)。
[] instanceof Array;        // true(正确)
{} instanceof Object;       // true(正确)
new Date() instanceof Date; // true(正确)
function(){} instanceof Function; // true(正确)

// 局限性
[] instanceof Object;       // true(数组也是对象,可能误判)
'abc' instanceof String;    // false(基本类型字符串不适用)
// 跨iframe场景失效(原型链不同)
3. Object.prototype.toString.call()(最准确的通用方法)
  • 原理:调用对象的 toString 方法,返回 [object 类型] 格式的字符串,不受原型链影响。
  • 适用场景:所有数据类型(包括 NullArray 等特殊类型)。
Object.prototype.toString.call(123);        // '[object Number]'
Object.prototype.toString.call('abc');      // '[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(Symbol());   // '[object Symbol]'
Object.prototype.toString.call(123n);       // '[object BigInt]'
Object.prototype.toString.call(new Date()); // '[object Date]'
4. 特殊类型的针对性判断
  • Array:除了 instanceoftoString,还可用 Array.isArray()(ES5+,最推荐):

    Array.isArray([]); // true
    Array.isArray({}); // false
    
  • Null:需单独判断(因 typeof null 有 bug):

    const a = null;
    a === null; // true(唯一可靠方法)
    
  • NaNNaN 是唯一不等于自身的值,需用 Number.isNaN()

    Number.isNaN(NaN); // true
    Number.isNaN('abc' / 1); // true(运算结果为NaN)
    
1. 问:typeof null 为什么返回 'object'
  • :这是 JS 最初实现的历史遗留 bug。早期 JS 用 32 位标记值表示数据类型,null 的标记位与对象相同(均为 0),导致 typeof 误判。该 bug 因兼容性问题未修复,需用 a === null 单独判断 null
2. 问:如何准确判断一个变量是数组还是对象?
    • Array.isArray() 直接判断数组:Array.isArray(arr) → 简洁可靠;
    • 或用 Object.prototype.toString.call()
      function isArrayOrObject(value) {
        const type = Object.prototype.toString.call(value);
        if (type === '[object Array]') return 'array';
        if (type === '[object Object]') return 'object';
        return 'other';
      }
      
3. 问:instanceoftypeof 的核心区别是什么?
    • typeof 基于数据类型的底层标记判断,适合基本类型,但无法区分引用类型;
    • instanceof 基于原型链判断,适合区分具体的引用类型(如 DateArray),但不适合基本类型,且受原型链修改影响。

四、总结

“判断 JS 数据类型需根据场景选择方法:

  • 基本类型(除 null)用 typeof
  • 引用类型(如 ArrayDate)用 Object.prototype.toString.call()instanceof
  • 数组优先用 Array.isArray()null 必须用 === null 判断。

实际开发中,Object.prototype.toString.call() 是最通用的方法,能覆盖所有类型;而针对数组、NaN 等特殊类型,有更简洁的专用 API(如 Array.isArrayNumber.isNaN)。”