- typeof:检测数据类型的运算符
- 返回结果是一个字符串,字符串中包含了对应的数据类型(number、string、boolean、undefined、symbol、bigint、object)typeof typeof xxx 结果都是’string‘
- 小bug:typeof null =》 object typeof按照计算机底层存储的二进制结果进行检测,object是以000开始的,null的二进制存储时000,所以会是别成object
- 所有对象都是以000开始的,所以基于typeof检测的结果都是object,也就是typeof无法细分是普通对象还是数组等对象
- instanceof
- 并不是用开检测数据类型的,是用来检测当前实例是否属于这个类
- 一般指应用于普通对象、数组对象、正则对象、日期对象等的具体细分
- 绝对不能证明instanceof Object为true就是普通对象
let arr = [];
console.log(arr instanceof Array)
console.log(arr instanceof Object)
console.log(arr instanceof RegExp)
- instanceof无法应用到原始值类型数值的检测上
let n = 10;
let m = new Number(10);
console.log(n.toFixed(2));
console.log(m.toFixed(2));
console.log(n instanceof Number)
console.log(m instanceof Number)
function Person(){}
Person.prototype=Array.prototype;
let p1 = new Person;
console.log(p1);
console.log(p1 instanceof Array)
- 基于‘实例 instanceof 类’检测是时候,浏览器底层是这样处理的 ‘类Symbol.hasInstance’
- Function.prototype[Symbol.hasInstance]=function Symbol.hasInstance{native code} 只有函数function.prototype上有这个方法
- Symbol.hasInstance方法执行原理
- 根据当前实例的原型链上(proto)是否存在这个类的原型(prototype)
- arr.proto===Array.prototype =>arr.instanceof Array=>true
- arr.proto.proto===Object.prototype =>arr.instanceof Object=>true
let arr = [];
console.log(arr.instanceof Array);
console.log(arr.instanceof Object);
console.log(Array[Symbol.hasInstance](arr))
let obj = {};
console.log(arr instanceof obj)
- constructor
- 原本就是获取市里的构造函数的,基于这些特点可以充当数据类型检测
- 比instanceof好用
- 但是也不准确:constructor是可以随意被修改的
let arr = []
console.log(arr.constructor === Array)
//在constructor不被修改的情况下,这样区分是数组还是普通对象
console.log(arr.constructor === Object)
console.log(arr.constructor === RegExp)//false
function Person(){}
Person.prototype=Array.prototype;
let p1 = new Person;
console.log(p1.constructor === Array);
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)或者({}).toString.call([value])
- 专门用来检测数据类型的,基本零瑕疵
- number/string/boolean/symbol/bigint/function/array/object...的原型上都有toString,除了Object.prototype.toString不是转换字符串的,其余都是,Object.prototype.toString说是用来检测数据类型的
- 返回结果‘[object 对象[Symbol.toStringTag]||对象的构造函数(不受自己修改的影响,对内置类有效))||Object]’
let class2type = {},
toString = class2type.toString
class Person {
get[Symbol.toStringTag](){
return "Person";
}
}
let p1 = new Person;
toString.call(p1)=>
重写instanceof
- obj-要检测的实例对象(不支持原始值类型)
- constructor-要检测类,必须是一个函数
function instance_of(obj,constructor) {
if(obj====null ||typeof obj!==(function||function)) return false;
if (typeof constructor !== 'function') throw new TypeError;
let proto = obj.__proto__,
prototype = constructor.prototype;
while(true){
if(proto === null) return false;
if(proto===prototype) return true;
proto = proto.__proto__;
}
}