js四种数据类型检测

181 阅读2分钟

1---

主题使用方法:github.com/xitu/juejin…

theme: juejin highlight: github

数据类型检测

typeof

  • 返回的结果是一个字符串,字符串中包含了对应的数据类型"number/string/boolean/undefined/symbol/bigint/object/function"
  • 因为检测结果返回的是一个字符串所以=> typeof typeof xxx 结果都是:“string”
  • typeof null =>"object"

由于在js中null等于什么都没有,表示一个空对象引用。而不同的对象在计算机底层的表现形式都为二进制,在javaScript中二进制的前三位为‘000’的话会被认定为object类型,而null的二进制表示全部为0,所以执行typeof会返回Object

  • typeof因此无法细分为普通对象还是数组等对象 instancof
  • 并不是专门用来检测数据类型的,而是用来检测当前实例是否属于这个类
  • 一般只用于普通对象/数组对象/正则对象/日期对象等的具体细分的
  • 无法应用到原始数据类型的检测上
  • 基于(实例 instanceof 类)检测的时候,浏览器底层是根据(类Symbol.hasInstance)来处理的
    • 根据当前实例的原型链上(proto)是否存在这个类的原型(prototype)
    • arr.__ proto__===Array.prototype => arr instranceof Array :true
    • arr.__ proto__.__ proto__===Object.prototype => arr instranceof Object :true
let arr = [];
console.log(arr instanceof Array);//=>true
console.log(arr instanceof Object);//=>true
console.log(Array[Symbol.hasinstance](arr));//=>true

constructor

  • 是用来获取实例的构造函数的,基于这些特点可以充当数据类型检测
  • 在原型没有重定向的时候还是可以区分数组和普通对象的
  • 一旦原型重定向,constructor也就不准了
let arr = [];
console.log(arr.constructor === Object); //false
console.log(arr.constructor === RegExp); //false */
原型被修改后
let a = function () {};
a.prototype = Array.prototype;
let a1 = new a;
console.log(a1.constructor === Array);//=>true
不区分字面量方式创建还是构造函数创建
let n = 10;
let m = new Number(10);
console.log(n.constructor === Number); //true
console.log(m.constructor === Number); //true

Object.prototype.toString.call([value])

  • 是专门用来检测数据类型的(非常强大,基本零瑕疵)
  • Number/String/Boolean/Symbol/BigInt/Function/Array/RegExp/Date/Object...的原型上都有toString方法,除了Object.prototype.tostring不是转换字符串的,其余都是,Object.prototype.tostrin是用来检测数据类型的
  • 返回结果"[Object 数据类型]"
  • 对于这些类型来说tostring()可以识别他们是因为引擎为他们设置好了tostringTag属性
  • 自己创建的类自然没有这个属性,tostring()找不到tostringTag属性时只好返回默认的Object标签,我们自己给他加上tostringTag自然就好了
 let class2type = {},
    toString = class2type.toString; //Object.prototype.toString

 class Person {
    // 只要获取实例的[Symbol.toStringTag]属性值,则调用这个方法
    get[Symbol.toStringTag]() {
        return "Person";
    }
}
let p1 = new Person; 
toString.call(p1) //=> "[object Person]"