JS之instanceof详解

JS之instanceof详解instanceof用于检测构造函数的prototype属性是否出现在某个实例对象的原型链上。语法:objectinstanceofconstructorobject:某个实例对象constructor:某个构造函数用来检测constructor.prototype是否存在于参数object的原型链上。示例//定义构造函数functionC(){}functionD(){}//实例化一个o对象varo=newC()//tru

大家好,又见面了,我是你们的朋友全栈君。

instanceof

用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。

  • 语法:object instanceof constructor
    • object:某个实例对象
    • constructor:某个构造函数

用来检测 constructor.prototype 是否存在于参数 object 的原型链上。

示例

// 定义构造函数
function C () { 
   }
function D () { 
   }
// 实例化一个 o 对象
var o = new C()
// true,true --> C.prototype 在 o 的原型链上
console.log(o instanceof C, o.__proto__ === C.prototype, '此时 o 的 __proto__:', o.__proto__, '此时 C 的 prototype:', C.prototype)
// false,false --> D.prototype 不在 o 的原型链上
console.log(o instanceof D, o.__proto__ === D.prototype)
// true true --> Object.prototype 在 o 的原型链上
console.log(o instanceof Object, o.__proto__.__proto__ === Object.prototype)
// 这时我们修改构造函数 C 的原型为一个空对象
C.prototype = { 
   }
// 实例化一个 o2 对象
var o2 = new C()
// true --> C.prototype 在 o2 的原型链上
console.log(o2 instanceof C)
// false,C.prototype 指向了一个空对象,这个空对象不在 o 的原型链上.
console.log(o instanceof C, '此时 o 的 __proto__:', o.__proto__, '此时 C 的 prototype:', C.prototype)
console.log('此时 D 的 prototype:', D.prototype);
// 继承
D.prototype = new C()
console.log('此时 D 的 prototype:', D.prototype);
var o3 = new D()
// true, true --> 因为 o3 是 构造函数 D new 出来的实例对象,所以 D.prototype 一定在 o3 的原型链上
console.log(o3 instanceof D, o3.__proto__ === D.prototype)
// true --> 因为 C.prototype 现在在 o3 的原型链上
console.log(o3 instanceof C)
// true,true --> 上面的结果为什么为 true 呢,看如下代码,D.prototype 是 构造函数 C new 出来的实例对象,所以 C.prototype 一定在 D.prototype 的原型链上
console.log(o3.__proto__ === D.prototype, D.prototype.__proto__ === C.prototype);
// true 相当于如下代码
console.log(o3.__proto__.__proto__ === C.prototype);

运行结果如图所示

JS之instanceof详解

一些容易出错的点

var simpleStr = "This is a simple string"; 
var myString = new String();
var newStr = new String("String created with constructor");
var myDate = new Date();
var myObj = { 
   };
var myNonObj = Object.create(null);

// 返回 false, simpleStr 并不是对象
simpleStr instanceof String;
// 返回 true
myString instanceof String;
// 返回 true
newStr instanceof String;
// 返回 true
myString instanceof Object;
// 返回 true
myObj instanceof Object;
// 返回 true
({ 
   }) instanceof Object;
// 返回 false, 一种创建非 Object 实例的对象的方法
myNonObj instanceof Object;
// 返回 false
myString instanceof Date;
// 返回 true
myDate instanceof Date;
// 返回 true
myDate instanceof Object;
// 返回 false
myDate instanceof String; 

Object.create(null) 会造成创建的对象其 __proto__ 指向为空

JS之instanceof详解

instanceof 判断基本数据类型的方法

其实就是自定义 instanceof 行为的一种方式,这里将原有的 instanceof 方法重定义,换成了 typeof,因此能够判断基本数据类型。

class PrimitiveNumber { 
   
  static [Symbol.hasInstance](x) { 
   
    return typeof x === 'number'
  }
}
// true
console.log(111 instanceof PrimitiveNumber)

手动实现一下instanceof的功能

function copyInstanceof (source, target) { 
   
    // 基本数据类型以及 null 直接返回 false
    if (!['function', 'object'].includes(typeof source) || source === null) return false
    // getProtypeOf 是 Object 对象自带的一个方法,能够拿到参数的原型对象
    let proto = Object.getPrototypeOf(source)
    while (true) { 
   
        // 查找到尽头,还没找到
        if (proto == null) return false
        // 找到相同的原型对象
        if (proto == target.prototype) return true
        proto = Object.getPrototypeOf(proto)
    }
}
console.log(copyInstanceof("111", String)); // false
console.log(copyInstanceof(new String("111"), String)); // true
console.log(copyInstanceof(Date, Function)); // true
console.log(copyInstanceof(null, Object)); // false
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/163371.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 使用VMware安装centos7并配置网络

    使用VMware安装centos7并配置网络准备工作:1.VM虚拟机(本文使用VMware14.1.2)2.Centos7安装包(https://www.centos.org/download/)centos官网提供多个版本下载,一般使用标准的DVD版安装版,大约4.2G。也可以使用mini版,后续自己安装第三方软件。各版本区别:https://wiki.centos.org/Manuals/ReleaseNotes/Cent…

    2022年6月6日
  • java报表插件_自定义报表 开源

    java报表插件_自定义报表 开源是一个基于Java的开源报表工具,它可以在Java环境下像其他IDE报表工具一样来制作报表,支持PDF、HTML、XLS、CSV和XML文件输出格式,是当前Java开发者最常用的报表工具。一个Eclipse-based开放源代码报表系统。它主要是用在基于Java与J2EE的Web应用程序上。BIRT主要由两部分组成:一个是基于Eclipse的报表设计和一个可以加到你应用服务的运行期组件。BIRT同…

    2022年10月20日
  • Oracle PL/SQL编程之五: 异常错误处理(知已知彼、百战不殆)

    Oracle PL/SQL编程之五: 异常错误处理(知已知彼、百战不殆)Oracle PL/SQL编程之五:异常错误处理(知已知彼、百战不殆) 本篇主要内容如下:5.1 异常处理概念5.1.1 预定义的异常处理5.1.2 非预定义的异常处理5.1.3 用户自定义的异常处理5.1.4  用户定义的异常处理5.2 异常错误传播5.2.1 在执行部分引发异常错误5.2.2 在声明

    2022年6月17日
  • C#之ArcGIS二次开发

    C#之ArcGIS二次开发根据图层名称获取图层publicIFeatureLayergetLayer(AxMapControlaxMapControl,stringlayerName){if(axMapControl.LayerCount>0){for(inti=0;i

    2022年6月26日
  • 模拟高并发请求_模拟驾驶怎么点火

    模拟高并发请求_模拟驾驶怎么点火转:模拟高并发的情况

    2022年4月21日
  • uniqueidentifier什么意思_数据类型int是什么意思

    uniqueidentifier什么意思_数据类型int是什么意思uniqueidentifier数据类型可存储16字节的二进制值,其作用与全局唯一标记符(GUID)一样。GUID是唯一的二进制数:世界上的任何两台计算机都不会生成重复的GUID值。GUID主要用于在用于多个节点,多台计算机的网络中,分配必须具有唯一性的标识符。在SQL中ROWGUIDCOL表示新列是行的全局唯一标识列。对于每个表只能指派一个uniqueidentifier列作为ROWGUI

    2022年9月4日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号