# 1、typeof

  用于检测数据类型的运算符。typeof的原理是按照计算机底层存储的二进制结果进行检测的,对象都是以000...开始的。

  • 返回结果是一个字符串,字符串包含了对应的数据类型 number/string/boolean/undefined/symbol/bigint/object/function
  • typeof nullobject
  • 所有对象都是以 000开始的,所以基于 typeof 检测的结果都是object

# 2、instanceof

  并不是用于检测数据类型的,是用来检测当前实例是否属于这个类。一般用来检测"普通对象、数组对象、正则对象、日期对象等"。无法应用到原始值类型数值的检测上。

  • 一旦 类的prototype 发生了改变,那么这个检测就不准了。
  • 基于 "实例 instanceof 类" 检测的时候,浏览器地层是这样处理的 "类Symbol.hasinstance"
  • Function.prototype[Symbol.hasinstance]=function [Symbol.hasinstance](){ [native code ]}
  • Symbol.hasInstance 方法执行的原理,是判断 类的prototype是否在实例的原型链上。
let arr = [];
console.log(arr instanceof Array);//true
console.log(Array[Symbol.hasInstance](arr));//true
console.log(arr instanceof Object);//true
1
2
3
4

instanceof的检测原理:

function instance_of (obj, constructor) {
    if (obj === null || !['object', 'function'].includes(typeof obj)) return false;
    if (typeof constructor !== "function") throw new TypeError("Right-hand side of 'instanceof' is not callable");
    let proto = Object.getPrototypeOf(obj), prototype = constructor.prototype;
    while (true) {
        if (proto === null) return false;
        if (proto === prototype) return true;
        proto = Object.getPrototypeOf(proto);
    }
}
console.log(instance_of(10, Number));//false
console.log(instance_of([], {}));//TypeError: Right-hand side of 'instanceof' is not callable
1
2
3
4
5
6
7
8
9
10
11
12

# 3、constructor

用于获取实例的构造函数,基于这些特点可以充当类型检测。但是可以手动修改实例的constructor属性。

let arr=[];
console.log(arr.constructor===Array) //true
console.log(arr.constructor===Object)//false 

let n=10;
let m=NUmber(10);
console.log(m.constructor===Number) //true 
console.log(n.constructor===Number) //true 在调用n.constructor时,实际上对n做了一层包装=> Number(n)
1
2
3
4
5
6
7
8

# 4、Object.prottype.toString.call(value)

  • 专门用于检测数据类型的。
  • Number/String/Boolean/Date/Symbol/BigInt/Function/Array/RegExp/Object...的原型上都有toString,除了Object.protortpe.toString不是转换字符串的,其余都是。Object.protortpe.toString是用来检测数据类型的。
  • 返回结果 "[object 对象[Symbol.toStrigTag]||对象的构造函数(不受自己更改的影响,对内置类有效)|Object]"
class Person{
    get [Symbol.toStringTag](){
        return "Person"
    }
}
const p1=new Person();
const toString={}.toString();
console.log(toString.call(p1));// [object Person]
1
2
3
4
5
6
7
8

检测类型的函数封装

function isType (typing) {
    return (val) => {
        return Object.prototype.toString.call(val) == `[object ${typing}]`;
    }
}
let utils = {};
['String', "Number", "Boolean", 'Object', "Date", "Function"].forEach(method => {
    utils['is' + method] = isType(method);
})
//测试
console.log(utils.isString('123'));//true
console.log(utils.isNumber(123));//true
1
2
3
4
5
6
7
8
9
10
11
12
Last Updated: 10/9/2020, 10:20:41 AM