`instanceof`运算符在判断对象类型时,可能会出现的错误

简介: ### `instanceof` 判断的常见问题
  1. 原型链被篡改导致的误判
    • 原理:在JavaScript中,instanceof是通过检查对象的原型链来判断类型的。如果原型链被意外地修改,就可能导致instanceof判断出错。
    • 示例:
      function Person() {
             }
      let p = new Person();
      // 手动修改对象p的原型链
      p.__proto__ = {
             };
      console.log(p instanceof Person);
      
    • 在这个例子中,原本p是Person构造函数的实例,p.__proto__指向Person.prototype。但是当我们手动将p.__proto__修改为一个新的空对象时,p instanceof Person会返回false,因为此时p的原型链已经不包含Person.prototype了,这就导致了误判。
  2. 跨iframe或window对象的判断问题
    • 原理:每个iframe和window都有自己独立的全局对象和执行环境,它们的原型链和对象构造方式可能不同。当试图在一个window或iframe环境中判断另一个环境中的对象类型时,instanceof可能无法正常工作。
    • 示例:
      // 在主页面
      function MainObject() {
             }
      let mainObj = new MainObject();
      let iframe = document.createElement('iframe');
      document.body.appendChild(iframe);
      let iframeWindow = iframe.contentWindow;
      // 尝试在iframe中判断主页面的对象
      iframeWindow.addEventListener('load', function () {
             
        try {
             
            console.log(iframeWindow.mainObj instanceof MainObject);
        } catch (e) {
             
            console.log("在iframe中判断主页面对象出现错误");
        }
      });
      
    • 在这个例子中,当在iframe的window环境中尝试判断主页面创建的mainObj对象是否是MainObject的实例时,很可能会出现错误。因为iframeWindow中的执行环境没有MainObject构造函数,并且对象的原型链在跨window环境时变得复杂,instanceof不能正确地按照预期进行判断。
  3. 多个库或框架对原型的修改冲突

    • 原理:在一个复杂的前端项目中,可能会使用多个库或框架。如果这些库或框架对同一个对象的原型或者全局的原型链进行了修改,那么instanceof的判断可能会受到干扰。
    • 示例:假设一个项目同时使用了两个库,库A和库B。库A对Array的原型进行了扩展,添加了一个新的方法newArrayMethod。库B在自己的代码逻辑中也对Array的原型进行了修改,可能改变了Array.prototype的指向或者添加了其他方法。此时,如果有一个数组对象,在使用instanceof判断它是否是Array的实例时,可能会因为两个库对Array原型的修改而出现不准确的结果。
  4. Symbol.hasInstance自定义行为导致的意外结果

    • 原理:在JavaScript中,可以通过在对象的Symbol.hasInstance方法中自定义instanceof的行为。如果不小心定义了不符合预期的Symbol.hasInstance行为,就会导致instanceof的判断出现意外结果。
    • 示例:
      class CustomClass {
             
        static [Symbol.hasInstance](obj) {
             
            return false;
        }
      }
      let testObj = {
             };
      console.log(testObj instanceof CustomClass);
      
    • 在这个例子中,CustomClass通过定义Symbol.hasInstance方法,使得无论传入什么对象,instanceof判断都会返回false,这与通常基于原型链的判断方式不同,会导致意外的结果。
相关文章
|
监控 网络协议 Java
Linux 网络编程从入门到进阶 学习指南
在上一篇文章中,我们探讨了 Linux 系统编程的诸多基础构件,包括文件操作、进程管理和线程同步等,接下来,我们将视野扩展到网络世界。在这个新篇章里,我们要让应用跳出单机限制,学会在网络上跨机器交流信息。
Linux 网络编程从入门到进阶 学习指南
|
Java 应用服务中间件 API
https+ip实现摄像头访问浏览器
https+ip实现摄像头访问浏览器
784 0
|
API 开发者
工作日和节假日api
节假日api核心服务托管在阿里云之上,API天然分布式、高可用。
|
JavaScript Docker 容器
使用Docker多阶段构建优化镜像大小
使用Docker多阶段构建优化镜像大小
672 100
|
JSON 监控 供应链
京东商品详情API参数构造指南:必填参数与自定义字段配置
京东商品详情API由京东开放平台提供,支持获取商品基础信息、价格库存、SKU规格等120+字段,适用于价格监控、库存管理等场景。接口采用HTTPS协议、JSON格式,数据延迟≤30秒,支持高并发。提供Python请求示例,便于快速接入。
|
存储 编解码 算法
超级好用的C++实用库之Base64编解码
超级好用的C++实用库之Base64编解码
1349 2
|
人工智能 文字识别 运维
AI多模态的5大核心关键技术,让高端制造实现智能化管理
结合大模型应用场景,通过AI技术解析高端制造业的复杂设备与文档数据,自动化地将大型零件、机械图纸、操作手册等文档结构化。核心技术包括版面识别、表格抽取、要素抽取和文档抽取,实现信息的系统化管理和高效查询,大幅提升设备维护和生产管理的效率。
839 7
|
存储 运维 监控
Entity Framework Core 实现审计日志记录超棒!多种方法助你跟踪数据变化、监控操作,超实用!
【8月更文挑战第31天】在软件开发中,审计日志记录对于跟踪数据变化、监控用户操作及故障排查至关重要。Entity Framework Core (EF Core) 作为强大的对象关系映射框架,提供了多种实现审计日志记录的方法。例如,可以使用 EF Core 的拦截器在数据库操作前后执行自定义逻辑,记录操作类型、时间和执行用户等信息。此外,也可通过在实体类中添加审计属性(如 `CreatedBy`、`CreatedDate` 等),并在保存实体时更新这些属性来记录审计信息。这两种方法都能有效帮助我们追踪数据变更并满足合规性和安全性需求。
848 1
|
缓存 前端开发 JavaScript
浏览器报错:net::ERR_CONTENT_LENGTH_MISMATCH 200 (OK)
浏览器报错:net::ERR_CONTENT_LENGTH_MISMATCH 200 (OK)
2999 0
|
JavaScript 前端开发
JavaScript基础知识:什么是原型链(Prototype Chain)?
JavaScript基础知识:什么是原型链(Prototype Chain)?
429 2