数据类型的检测

❗️首先要明确常见的八种数据类型:

  1. 基本数据类型
    • string
    • number
    • boolean
    • null
    • undefined
    • bigint
    • symbol
  2. 复杂数据类型
    • object

1. typeof

  • typeof 是一元运算符,用法:typeof value
  • 输出值:上面所说的八种类型(除null之外加上个function)

注意点

  1. typeof null 输出值为Object,这个是历史遗留问题;

  2. typeof function(){}输出值为function

  3. []{}function(){}输出值都为Object,也就是typeof只能精准判断除了null之外的基本类型,无法判断复杂数据类型(除function外);

    类型输出值原因
    nullobject历史遗留问题
    其他原始类型对应类型字符串准确识别
    function(){}function函数属于function类型
    [] / {} / Date / RegExp等object-(无法具体区分object的具体类型)

2. instanceof

  • instanceof 是二元运算符,用法:object instanceof type
  • 输出值:true 或 false

注意点

  1. instanceof是在检测对象的隐式原型链的任意位置是否存在构造函数的原型;
  2. 能检测对Object的具体类型,如FunctionArrayObject等;

3. constructor

  • constructor 是对象的构造函数的显式原型上的属性,用法:object.constructor
  • 输出值:对象所属的构造函数

注意点

  1. constructor 是属性,不是运算符,用法:object.constructor
  2. constructor 可以进行修改
let obj = []

console.log(obj.constructor) // Array (在obj的隐式原型链上寻找构造函数的原型,再从上面获取constructor属性)

obj.constructor = Function(){}

console.log(obj.constructor) // Function

4. Object.prototype.toString.call()

能准确判断数据类型,包括ES6+出的数据类型(如:MapSetWeakSetWeakMap等)

🚌总结:

方法核心原理优点缺点
typeof内部类型标志位推测快速简单无法检测出[] / {}以及对象的具体类型(如Date、RegExp第二个)
instanceof检测显示原型是否在对象隐式原型链上检测对象是否为构造函数实例,支持继承无法检测原始类型
constructor显式原型的构造函数属性检测是否是某个构造函数的实例原始类型检测不准确;nul/undefined检测会出错;而且易被修改
Object.prototype.toString.call利用Object的固有属性准确检测类型(包括ES6+新类型)写法麻烦