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]
相关文章
|
网络安全
charles抓包显示乱码解决方法
【问题现象】 在抓https协议请求时,Request和Response显示乱码了: 【解决办法】 第一步:点击 【工具栏-->Proxy-->SSL Proxying Settings...】   第二点:添加需求抓包的请求的域名和端口号:   重新抓包,Request显示正常:   PS: 问题解决起来并没有太复杂,不过在网上搜索的资料试过很多都没有起做用,遂在此做个记录。
10284 0
C# .net webapi使用swagger时显示controller注释
C# .net webapi使用swagger时显示controller注释
513 0
|
SQL 消息中间件 关系型数据库
实时计算 Flink版产品使用问题之元数据血缘可以通过什么来获取
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
芯片
EDA设计:探索电子设计的自动化之路
EDA设计:探索电子设计的自动化之路
770 0
|
存储 网络安全 开发工具
Git版本控制工具详解(二)
Git版本控制工具详解
288 0
|
11月前
|
JavaScript
vue尚品汇商城项目-day06【43.微信支付业务】
vue尚品汇商城项目-day06【43.微信支付业务】
113 0
|
监控 NoSQL 关系型数据库
一文吃透企业级elk技术栈:5. logstatsh 安装配置
一文吃透企业级elk技术栈:5. logstatsh 安装配置
|
API 数据安全/隐私保护
uniapp中的uview组件库丰富的Keyboard 键盘 用法
uniapp中的uview组件库丰富的Keyboard 键盘 用法
566 0
经过两年努力,我终于进入腾讯(PCG事业群4面总结)
为什么要尽量让自己进大厂? 如果毕业就进了大厂,那你将得到业内大牛的指导,以及随处可见的技术碰撞。新技术的跟进也是非常快的,在这样的环境中,你的技术成长自然是非常快的。如果自己足够努力,用不了三年,你可能也将会跟他们水平差不多。 所以,明白这一点的我,很早就已经立下志愿,目标是鹅厂。经过我两年的努力,付出就是有回报的,我总算进入了腾讯工作。下面分享一下我自己的4面面经,PCG事业群。
|
存储 前端开发 easyexcel
谷粒学院——Day06【整合阿里云OSS、EasyExcel技术实现Excel导入分类】
谷粒学院——Day06【整合阿里云OSS、EasyExcel技术实现Excel导入分类】
1412 0
谷粒学院——Day06【整合阿里云OSS、EasyExcel技术实现Excel导入分类】