JavaScript类型判断四大法

92 阅读3分钟

类型判断在编程、数据处理、逻辑控制等场景中是核心操作,其应用覆盖各个开发环节,接下来让我们学习JavaScript中类型判断的主要四个方法,了解它们的优缺点和适用场景,以便更好的使用它们。

typeof

typeof undefined;        // "undefined"
typeof 42;               // "number"
typeof "hello";          // "string"
typeof true;             // "boolean"
typeof Symbol();         // "symbol"
typeof 123n;             // "bigint"
typeof function() {};    // "function"
typeof [1, 2, 3];        // "object" (数组属于特殊对象)
typeof null;             // "object" (历史遗留bug)
typeof new Date();       // "object"
typeof /regex/;          // "object"
  1. typeof 可以准确判断除了null以外的基本类型
  2. typeof 对于引用类型来说,除了function会返回function,其他的都返回object

工作原理

  • typeof 是通过将值转换为二进制来判断类型的,对于二进制前三位是 0 的统一识别为对象,所有的引用类型二进制前三位都是0,而null全是0

instanceof

const arr = [1, 2, 3];
arr instanceof Array; // true 

arr instanceof Object; // true(所有对象都是Object的实例) 

const date = new Date(); 
date instanceof Date; // true 

class Person {} 
const p = new Person(); 
p instanceof Person; // true

instanceof 可以准确的判断复杂引用类型,但是不能正确判断基本数据类型

工作原理

instanceof 内部机制是通过检查对象的原型链中是否包含指定构造函数的 prototype 属性, 基本类型默认不访问原型,所以不能正常判断基本数据类型

用代码来描述是不是更易懂一些

function myInstanceof(L,R){
    L=L.__proto__;
    while(L){
        if(L===R.prototype){
            return true
        }
        L=L.__proto__;
    }
    return false
}

Object.propotype.toString.call()

Object.prototype.toString.call(undefined); // "[object Undefined]" 

Object.prototype.toString.call(null); // "[object Null]" 

Object.prototype.toString.call(42); // "[object Number]" 

Object.prototype.toString.call([1, 2, 3]); // "[object Array]" 

Object.prototype.toString.call(/regex/); // "[object RegExp]" 

Object.prototype.toString.call(new Date()); // "[object Date]" 

Object.prototype.toString.call(function() {}); // "[object Function]"

  1. 能够准确识别对象的具体类型,包括内置对象和自定义对象。
  2. 适用于所有数据类型,包括基本数据类型和复杂数据类型。
  3. 返回一个格式为[object Type]的字符串,其中Type表示对象的类型。

工作原理

Object.prototype.toString ( )

来自--Annotated ES5

  1. 如果this值未定义,返回"[object undefined]"
  2. 如果this值为null,则返回"[object null]"
  3. object为传递this值作为参数调用toObject的结果。
  4. class为对象的内部属性[[class]]的值。
  5. 返回三个字符串“[object ”, class和“]”连接后的String值。

Object.propotype.toString.call()

在 Object.prototype.toString.call(obj) 中:

  • this 被绑定到 obj,即 toString() 方法执行时的上下文对象是 obj
  • obj 的 [[Class]] 属性被读取,生成对应的类型字符串。

Array.isArray()

判断一个值是否为数组。

Array.isArray([1, 2, 3]); // true 

Array.isArray({}); // false

总结

方法适用场景优点缺点
typeof基本类型判断(除 null简单、性能高无法区分对象、数组等
instanceof对象是否为特定构造函数的实例支持自定义类不支持基本类型、跨窗口问题
Object.prototype.toString精确判断所有内置类型最全面、最可靠语法冗长
Array.isArray()判断数组专门为数组设计只能判断数组

根据具体场景选择合适的方法,通常优先使用 typeof 和 Array.isArray(),复杂场景使用 Object.prototype.toString