数据类型检测的手段:

  • typeof
    • 底层机制:直接在计算机底层基于数据类型的值(二进制)进行检测
    • 特点:
      • tyepof null 结果为:"object" 对象存储在计算机中,都是以000开始的二进制存储,null也是,所以检测出来的结果是对象(可以理解为计算机的bug)
      • typeof 普通对象/数组对象/正则对象/日期对象 结果为:"object"
  • instanceof 检测当前实例是否属于这个类的
    • 底层机制:只要当前类出现在实例的原型链上,结果都是true
    • 特点:
      • 由于我们可以肆意的修改原型的指向,所以检测出来的结果是不准的
      • 不能检测基本数据类型
  • constructor
    • 用起来看似比instanceof还好用一些(基本类型支持的)
    • constructor可以随便改,所以也不准
  • Object.prototype.toString.call([value])
    • 标准检测数据类型的办法:Object.prototype.toString不是转换为字符串,是返回当前实例所属类的信息
    • 标准检测的办法 “[object Number/String/Boolean/Null/Undefined/Symbol/Object/Array/RegExp/Date/Function]”

toString

  1. const obj = {
  2. name: '珠峰培训'
  3. };
  4. console.log(obj.toString()) // "[object Object]"
  5. // toString方法执行,this是obj,所以检测是obj它的所属类信息
  6. // 推测:是不是只要把Object.prototype.toString执行,让它里面的this变为要检测的值,那就能返回当前值所属类的信息

constructor

  1. let arr = [];
  2. console.log(arr.constructor === Array); // true
  3. console.log(arr.constructor === RegExp); // false
  4. console.log(arr.constructor === Object); // false
  5. Number.prototype.constructor = 'AA';
  6. let n = 1;
  7. console.log(n.constructor === Number); // false

instanceof

  1. // 只要处于原型链上,结果就为true
  2. const arr = []
  3. console.log(arr instanceof Array) // true
  4. console.log(arr instanceof RegExp) // false
  5. console.log(arr instanceof Object) // true
  1. // 可以肆意修改原型指向
  2. function Fn() {}
  3. Fn.prototype = Object.create(Array.prototype)
  4. const f = new Fn
  5. console.log(f instanceof Array) // true
  1. // 不能检测基本数据类型
  2. console.log(1 instanceof Number) // false
  1. // 自己封装
  2. function instance_of(example, classFunc) {
  3. const classFuncPrototype = classFunc.prototype
  4. const proto = Object.getPrototypeOf(example) // example.__proto__
  5. while (true) {
  6. if (proto === null) {
  7. // Object.prototype.__proto__ => null
  8. return false
  9. }
  10. if (proto === classFuncPrototype) {
  11. // 查找过程中发现有,则证明实例是这个类的一个实例
  12. return true
  13. }
  14. proto = Object.getPrototypeOf(proto)
  15. }
  16. }
  17. // 实例.__proto__===类.prototype
  18. const arr = []
  19. console.log(instance_of(arr, Array))
  20. console.log(instance_of(arr, RegExp))
  21. console.log(instance_of(arr, Object))

封装万能类型检测

  1. (function () {
  2. var class2type = {};
  3. var toString = class2type.toString; //=>Object.prototype.toString
  4. // 设定数据类型的映射表
  5. ["Boolean", "Number", "String", "Function", "Array", "Date", "RegExp", "Object", "Error", "Symbol"].forEach(name => {
  6. class2type[`[object ${name}]`] = name.toLowerCase();
  7. });
  8. function toType(obj) {
  9. if (obj == null) {
  10. // 传递的值是null或者undefined,就返回对应的字符串
  11. return obj + "";
  12. }
  13. // 基本数据类型都采用typeof检测
  14. return typeof obj === "object" || typeof obj === "function" ?
  15. class2type[toString.call(obj)] || "object" :
  16. typeof obj;
  17. }
  18. window.toType = toType;
  19. })();