JavaScript 数据类型判断的多种方法详解与对比

作者:异步漫步时间:2026-10-25 03:23:06浏览:312

本文深入探讨 JavaScript 中判断数据类型的几种常用方法。首先分析 typeof 在处理 null 和复杂类型时的局限性,接着介绍 instanceof 基于原型链的判断逻辑及其对基本类型的不足。重点讲解 Object.prototype.toString.call() 的通用性,并补充 constructor、Array.isArray() 及正则匹配等辅助手段,帮助开发者根据场景选择最合适的类型判断方案。

前言

JavaScript 属于动态类型语言,变量在声明至使用的过程中可能跨越多个函数调用,其数据类型随之变化。因此,准确判断变量当前所属的数据类型显得尤为关键。

typeof 是否能正确判断类型?

typeof 是一个操作符,右侧需跟随一个一元表达式,用于返回该表达式的原始数据类型。返回值是以全小写字母表示的类型字符串,涵盖以下七种:number、boolean、symbol、string、object、undefined 以及 function。

受历史遗留问题影响,typeof 在判断原始类型时存在特例:typeof null 会返回 'object'。此外,对于对象(Object)和数组(Array)等复杂类型,typeof 统一返回 'object'。具体表现见下方示例。


    typeof 1 // 'number'
    typeof "1" // 'string'
    typeof null // 'object'
    typeof undefined // 'undefined'
    
    typeof [] // 'object'
    typeof {} // 'object'
    typeof function() {} // 'function'

由此可见,typeof 适用于基本数据类型的判断,但除 function 外,难以准确区分其他复杂数据类型。为此,可引入第二种方法,该方法既可用于判断复杂类型,也能辅助判断基本类型。

当 typeof 返回值为 'object' 时,实际可能对应三种情况:

  • 值为 null
  • 值为 object
  • 值为 array

针对 null,可直接使用严格等于运算符 === 进行判断。至于数组和对象的区分,后续将详细展开。

instanceof 是否能正确判断类型?

instanceof 运算符用于检测左侧对象是否为右侧构造函数的实例,语法为 A instanceof B。若 A 是 B 的实例,则返回 true,否则返回 false。

instanceof 的判断依据是原型链。然而,对于对象而言,数组(Array)也会被识别为 Object 的实例,且该方法无法区分基本类型的 string 和 boolean。虽然可以通过左侧放置待判断内容、右侧放置类型来尝试判断,但 instanceof 本质上仅适用于检测构造函数(右侧)的 prototype 属性是否存在于实例对象(左侧)的原型链上,因此仅适合判断复杂数据类型。具体表现见下方示例。


    function Func() {}
    const func = new Func()
    console.log(func instanceof Func) // true
    
    const obj = {}
    const arr = []
    obj instanceof Object // true
    arr instanceof Object // true
    arr instanceof Array // true
    
    const str = "abc"
    const str2 = new String("abc")
    str instanceof String // false
    str2 instanceof String // true

单独使用 instanceof 存在局限,结合前文 typeof 无法区分数组和对象的结论,我们可以将两者结合,构建一个更完整的类型判断逻辑。


    function myTypeof(data) {
        const type = typeof data
        if (data === null) {
            return 'null'
        }
        if (type !== 'object') {
            return type
        }
        if (data instanceof Array) {
            return 'array'
        }
        return 'object'
    }

Object.prototype.toString.call()

前文通过 typeof 和 instanceof 实现了初步的类型判断,是否存在更简洁的代码实现方式?答案是使用 Object.prototype.toString.call()。

每个对象都拥有 toString() 方法,当需要将对象转换为文本值或以预期字符串形式引用对象时,会自动调用该方法。默认情况下,从 Object 派生的所有对象均继承此方法。若自定义对象未覆盖该方法,toString 将返回特定格式字符串。


    Object.prototype.toString.call(new Date()) // [object Date]
    Object.prototype.toString.call("1") // [object String]
    Object.prototype.toString.call(1) // [object Numer]
    Object.prototype.toString.call(undefined) // [object Undefined]
    Object.prototype.toString.call(null) // [object Null]

综合上述知识点,我们可以封装出一个通用的类型判断方法。


    function myTypeof(data) {
        var toString = Object.prototype.toString;
        var dataType = data instanceof Element ? "element" : toString.call(data).replace(/\[object\s(.+)\]/, "$1").toLowerCase()
        return dataType
    };

    myTypeof("a") // string
    myTypeof(1) // number
    myTypeof(window) // window
    myTypeof(document.querySelector("h1")) // element

constructor

constructor 判断方式与 instanceof 类似,但 constructor 在检测 Object 类型时表现不同,且能够处理基本数据类型的检测,不仅限于对象类型。

注意以下几点:

1. null 和 undefined 没有 constructor 属性;

2. 判断数字时需使用括号,例如 (123).constructor,若直接写作 123.constructor 会引发报错;

3. 在类继承场景下,constructor 可能出现误判,因为 Object 被覆盖后,检测结果将不再准确。


    function A() {};
    function B() {};
    A.prototype = new B();
    console.log(A.constructor === B)  // false

    var C = new A();
    console.log(C.constructor === B)  // true
    console.log(C.constructor === A)  // false 

    C.constructor = A;
    console.log(C.constructor === A);  // true
    console.log(C.constructor === B);  // false

Array.isArray()

Array.isArray() 方法用于确定传入的值是否为 Array 类型。若对象确为数组,则返回 true,否则返回 false。


    Array.isArray([1, 2, 3]); // true
    Array.isArray({foo: 123}); // false
    Array.isArray("foobar"); // false
    Array.isArray(undefined); // false

正则判断

我们可以将对象和数组转换为字符串,进而通过格式匹配来判断最终类型。


    function myTypeof(data) {
        const str = JSON.stringify(data)
        if (/^{.*}$/.test(data)) {
            return 'object'
        }
        if (/^\[.*\]$/.test(data)) {
            return 'array'
        }
    }

总结

至此,关于 JavaScript 中数据类型正确判断方法的介绍已完成。如需了解更多 JS 数据类型判断相关内容,欢迎查阅本站往期文章或继续浏览后续相关文章,感谢大家的支持。

至此,关于 JavaScript 中数据类型正确判断方法的介绍已完成。如需了解更多 JS 数据类型判断相关内容,欢迎查阅本站往期文章或继续浏览后续相关文章,感谢大家的支持。

作者最新文章