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

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

一、typeof

1. typeof 优点?缺点?

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

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

2. typeof 作用?

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

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

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

4. typeof 注意事项        

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 是操作符

原因:

typeof 的返回值之一为'function',如果 typeof 为 function,那么 typeof(typeof) 会返回'function',但是经测试,上述代码浏览器会抛出错误。因此可以证明 typeof 并非函数。

既然 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都是判断数据类型的方法,区别如下:        


typeof会返回一个变量的基本类型,instanceof返回的是一个布尔值

instanceof 可以准确地判断复杂引用数据类型,但是不能正确判断基础数据类型

而 typeof 也存在弊端,它虽然可以判断基础数据类型(null 除外),但是引用数据类型中,除了 function 类型以外,其他的也无法判断

五、模拟实现一个 instanceof

  思想:沿原型链往上查找

    instance_of (Case, Constructor) {
      console.log('Case:', typeof Case, 'Constructor1:', typeof Constructor);
      // 基本数据类型 返回false
      if ((typeof (Case) != 'object' && typeof (Case) != 'function') || Case == 'null') return false
      let CaseProto = Object.getPrototypeOf(Case);
      console.log('CaseProto:', CaseProto);
      console.log('Constructor:', Constructor.prototype);
      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]
相关文章
|
6月前
|
JavaScript 前端开发
typeof的作用
typeof的作用
32 0
|
17天前
|
前端开发 JavaScript
|
6月前
Object.prototype.toString.call() 和 instanceOf 和 Array.isArray() 区别以及优缺点
Object.prototype.toString.call() 和 instanceOf 和 Array.isArray() 区别以及优缺点
51 0
|
JavaScript 前端开发
typeof 类型判断
typeof 类型判断
68 1
|
6月前
|
存储 设计模式 缓存
Java instanceof操作符:类型检查的必备工具
Java instanceof操作符:类型检查的必备工具
89 0
|
6月前
|
JavaScript 前端开发 测试技术
探究 JavaScript 类型检查的利器:typeof 和 instanceof
探究 JavaScript 类型检查的利器:typeof 和 instanceof
|
11月前
|
JavaScript 前端开发
JavaScript学习(六十三)—typeof和instanceof检测数据类型的异同
JavaScript学习(六十三)—typeof和instanceof检测数据类型的异同
|
存储 数据库
案例09-数据类型不一致导致equals判断为false
数据类型不一致导致equals判断为false
案例09-数据类型不一致导致equals判断为false
|
JavaScript 前端开发 Java
为什么使用typeof判断数据类型的时候null出来是object?
为什么使用typeof判断数据类型的时候null出来是object?