第一种:Typeof

  1. typeof 检测数据类型
    console.log(typeof 10); // number
    
    console.log(typeof 'name'); // string
    
    console.log(typeof true); // boolean
    
    console.log(typeof undefined); // undefined
    
    console.log(typeof Symbol(100)); // symbol
    
    console.log(typeof function fn() { }); // function
    
    console.log(typeof typeof []); //=>"string"
    
    console.log(typeof null); // object
    console.log(typeof {}); // object
    console.log(typeof new RegExp(/A/)); // object
    console.log(typeof []); // object"
    
  2. 局限性:
    1. 只能区分 基本数据类型,不能判断 引用数据类型
    2. 不能区分 null引用数据类型

第二种:Object.prototype.toString

  1. Symbol.toStringTag 是一个内置 symbol 类型的值,它通常作为对象的属性键使用,对应的属性值应该为字符串类型,这个字符串用来表示该对象的自定义类型标签;

  2. 通常只有内置的 Object.prototype.toString() 方法会去读取这个标签并把它包含在自己的返回值里;

  1. 检测数据类型

    ({}).toString.call(250)       // "[object Number]"
    
    ({}).toString.call(true)      // "[object Boolean]"
    
    ({}).toString.call('')        // "[object String]"
    
    ({}).toString.call([])        // "[object Array]"
    
    ({}).toString.call(null)      // "[object Null]"
    
    Object.prototype.toString.call(undefined) // "[object Undefined]"
    
    Object.prototype.toString.call({})        // "[object Object]"
    
    Object.prototype.toString.call(/^.$/)     // "[object RegExp]"
    
    Object.prototype.toString.call(() => { }) // "[object Function]"
    
  2. 局限性:

    1. 只能检测出是 object 类型,不能细分是谁的实例 (可利用 Symbol.toStringTag 做一些特殊处理实现检测自定义类型)
      JavaScript
      JavaScript
      // 不能校验自定义类型
      class Cat { }
      let cat = new Cat();
      
      console.log(Object.prototype.toString.call(cat)); // [object Object]
      
      class Cat { }
      let cat = new Cat();
      Object.defineProperty(cat, Symbol.toStringTag, { value: '猫' }); // [object 猫]
      
      console.log(Object.prototype.toString.call(cat));
      

第三种:instanceof

  1. 检测某个实例是否属于这个类,所有出现在其原型链上的类,检测结果都是 true

    console.log(12 instanceof Number); // false
    console.log(new Number(12) instanceof Number); // true
    
    console.log([] instanceof Array); // true
    console.log([] instanceof Object); // true
    
  2. 局限性:

    1. 基本数据类型的值,连对象都不是,更没有 __proto__ ,虽说也是所属类的实例,在 JS 中也可以调取所属类原型上的方法,但是 instanceof 是不认的;
    2. 由于可以基于 __proto__ 或者 prototype 改动原型链的动向,所以基于 instanceof 检测出来的结果并不一定是准确的;
      function Fn() { }
      let f = new Fn();
      console.log(f instanceof Array); // false
      
      //原型链:f -> Fn.prototype -> Object.prototype
      Fn.prototype.__proto__ = Array.prototype; // 改变原型指向
      //原型链:f -> Fn.prototype -> Array.prototype -> Object.prototype
      console.log(f instanceof Array); // true
      

第四种:constructor

  1. 在类的原型上一般都会带有 constructor 属性,存储当前类本身,也是利用这一点,获取实例的 constructor 属性值,验证是否为所属的类,从而进行数据类型检测;

    console.log(12.constructor === Number); // true
    
  2. 局限:

    1. constructor 属性值太容易被修改;
    2. 除了 nullundefinedconstructor 可以正确检测出原始类型和对象类型;

面试题

实现 instanceof 关键字

function _instanceof(A, B) {
  while (B.prototype) {
    if (A.__proto__ == B.prototype) {
      return true
    } else {
      B = B.prototype
    }
  }
  return false
}

console.log(_instanceof('a', String)); // true
打赏作者
您的打赏是我前进的动力
微信
支付宝
评论

中午好👏🏻,我是 ✍🏻   疯狂 codding 中...

粽子

这有关于前端开发的技术文档和你分享。

相信你可以在这里找到对你有用的知识和教程。

了解更多

目录

  1. 1. 第一种:Typeof
  2. 2. 第二种:Object.prototype.toString
  3. 3. 第三种:instanceof
  4. 4. 第四种:constructor
  5. 5. 面试题
    1. 5.1. 实现 instanceof 关键字