typeof 与 instanceof ,如何模拟实现一个 instanceof,有没有通用检测数据类型?

书山有路勤为径,学海无涯苦作舟!!!金三银四,面试加油;冲!!! 

一、typeof

1. typeof 优点?缺点?

优点:能够快速区分基本数据类型

缺点:不能将Object、Array和Null区分,都返回object

2. typeof 作用?

        区分数据类型,可以返回7种数据类型:numberstringbooleanundefinedobjectfunction ,以及 ES6 新增的 symbol

3. typeof 能正确区分数据类型吗?

        不能。对于原始类型,除 null 都可以正确判断;对于引用类型,除 function 外,都会返回 "object"

4. typeof 注意事项        

  • typeof 返回值为 string 格式,注意类似这种考题: typeof(typeof(undefined)) -> "string"
  • typeof 未定义的变量不会报错,返回 "undefiend"
  • typeof(null) -> "object": 遗留已久的 bug
  • typeof无法区别数组与普通对象: typeof([]) -> "object"
  • typeof(NaN) -> "number"

5. typeof为什么对null错误的显示

        这只是 JS 存在的一个悠久 Bug。在 JS 的最初版本中使用的是 32 位系统,为了性能考虑使用低位存储变量的类型信息,000 开头代表是对象然而 null 表示为全零,所以将它错误的判断为 object

6. typeof('abc')和 typeof 'abc'都是 string, 那么 typeof 是操作符还是函数?

    答案:typeof 是操作符

    原因:

  1. typeof 的返回值之一为'function',如果 typeof 为 function,那么 typeof(typeof) 会返回'function',但是经测试,上述代码浏览器会抛出错误。因此可以证明 typeof 并非函数。
  2. 既然 typeof 不是函数,那 typeof 后面的括号的作用是?

    括号的作用是进行分组而非函数的调用。—— 《javascript 高级程序设计》

二、实现一个 typeof

function _typeof(value){
    
    return Object.prototype.toString.call(value).slice(8,-1).toLowerCase();
}

三、instanceof原理     

    优点:能够区分Array、Object和Function,适合用于判断自定义的类实例对象 缺点:Number,Boolean,String基本数据类型不能判断

    ① instanceof 判断对象的原型链上是否存在构造函数的原型。只能判断引用类型。

    ② instanceof 常用来判断 A 是否为 B 的实例

 // A是B的实例,返回true,否则返回false

 // 判断A的原型链上是否有B的原型

 A instaceof B

四、typeof 与 instanceof 的区别

    typeof与instanceof都是判断数据类型的方法,区别如下:        

  1. typeof会返回一个变量的基本类型,instanceof返回的是一个布尔值
  2. instanceof 可以准确地判断复杂引用数据类型,但是不能正确判断基础数据类型
  3. 而 typeof 也存在弊端,它虽然可以判断基础数据类型(null 除外),但是引用数据类型中,除了 function 类型以外,其他的也无法判断

五、模拟实现一个 instanceof

    思想:沿原型链往上查找

    instance_of (Case, Constructor) {
      // 基本数据类型 返回false
      if ((typeof (Case) != 'object' && typeof (Case) != 'function') || Case == 'null') return false
      let CaseProto = Object.getPrototypeOf(Case);

      while (true) {
        // 查到原型链顶端,仍未查到,返回false
        if (CaseProto == null) return false;
        // 找到相同类型
        if (CaseProto == Constructor.prototype) return true;
        CaseProto = Object.getPrototypeOf(CaseProto)
      }
    },
    function A () { }
    function B () { }
    const C = new A();
    const D = new B();
    console.log(this.instance_of(C, A)); // true
    console.log(this.instance_of(D, B)); // true
    console.log(this.instance_of(C, Array)); // false

  

六、通用监测数据类型:Object.prototype.toString.call()

    优点:精准判断数据类型 缺点:写法繁琐不容易记,推荐进行封装后使用 

Object.prototype.toString.call(()=>{})       // [object Function]
Object.prototype.toString.call({})           // [object Object]
Object.prototype.toString.call([])           // [object Array]
Object.prototype.toString.call('')           // [object String]
Object.prototype.toString.call(22)           // [object Number]
Object.prototype.toString.call(undefined)    // [object undefined]
Object.prototype.toString.call(null)         // [object null]
Object.prototype.toString.call(new Date)     // [object Date]
Object.prototype.toString.call(Math)         // [object Math]
Object.prototype.toString.call(window)       // [object Window]

猜你喜欢

转载自blog.csdn.net/weixin_56650035/article/details/122864752