写点什么

instanceof 运算符的实质:Java 继承链与 JavaScript 原型链

用户头像
zhoulujun
关注
发布于: 3 小时前

Java instanceofinstanceof 严格来说是 Java 中的一个双目运算符,用来测试一个对象是否为一个类的实例


boolean result = obj instanceof Class


其中 obj 为一个对象,Class 表示一个类或者一个接口,当 obj 为 Class 的对象,或者是其直接或间接子类,或者是其接口的实现类,结果 result 都返回 true,否则返回 false。


总结就是:


只要判断对象 obj 在 属于 Class 的继承链上,就返回 true


obj 必须为对象,因此 obj 必须为引用类型,不能是基本类型


基本数据类型:byte short int long float double char boolean


特殊类型:null


该类型没有名字,所以不可能声明为 null 类型的变量或者转换为 null 类型,null 引用是 null 类型表达式唯一可能的值,null 引用也可以转换为任意引用类型


如果 obj 为 null,那么将返回 false。


编译器会检查 obj 是否能转换成右边的 class 类型,如果不能转换则直接报错,如果不能确定类型,则通过编译,具体看运行时定。


java 数据类型看参看《再谈 Java 数据结构—分析底层实现与应用注意事项》


JavaScript 数据结构参看《再谈 js 对象数据结构底层实现原理-object array map set》


对于前端,这里只是一个引子


JavaScript instanceofThe instanceof operator tests whether the prototype property of a constructor appears anywhere in the prototype chain of an object.


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


instanceof 操作符的内部实现机制和隐式原型、显式原型有直接的关系。instanceof 的左值一般是一个对象,右值一般是一个构造函数,用来判断左值是否是右值的实例。它的实现原理是沿着左值的__proto__一直寻找到原型链的末端,直到其等于右值的 prototype 为止。


instanceof 的作用是判断一个对象是不是一个函数的实例。比如 obj instanceof fn, 实际上是判断 fn 的 prototype 是不是在 obj 的原型链上。所以


instanceof 运算符的实质:用来检测 constructor.prototype 是否存在于参数 object 的原型链上。


原生 JS 实现 instanceof 功能核心就是左边对象的__proto__的指向是否等于右边的 prototype 属性


function instanceofMethod (left, right) {let prototype = right.prototype;let proto = left.proto;while (true) {if (proto === prototype) return true;if (proto === null) return false;//若本次查找无结果,则沿着原型链向上查找 proto = proto.proto;}}在《再谈 javascriptjs 原型与原型链及继承相关问题》


JavaScript 原型链构造图


根据上图展示的 Object 和 Function 的继承依赖关系,我们可以通过 instanceof 操作符来看一下 Object 和 Function 的关系:


console.log(Object instanceof Object); // trueconsole.log(Object instanceof Function); // trueconsole.log(Function instanceof Object); // trueconsole.log(Function instanceof Function); // true 函数与对象相互依存,分别定义了事物的描述方法和事物的生成方法,在生成 JS 万物的过程中缺一不可。


Function instanceof Function // true, why? Function.prototype 是原型对象,却是函数对象 Object 特殊在 Object.prototype 是凭空出来的。语法上,所有的{}都会被解释为 new Object();


Function 特殊在__proto__ == prototype。语法上,所有的函数声明都会被解释为 new Function()。


我们来看 Function 和 Object 的特殊之处:


Object 是由 Function 创建的:因为 Object.proto === Funciton.prototype;


同理,Function.prototype 是由 Object.prototype 创建的;


Funciton 是由 Function 自己创建的!


Object.prototype 是凭空出来的!


null instanceof null 基本包装类型对象:ECMAScript 还提供了 3 个特殊的引用类型: Boolean、Number、String。这些类型与其他内置对象类型相似,但同时具有各自的基本类型相应的特殊行为。实际上,每当读取一个基本类型值得时候,后台就会创建一个对应的基本包装类型的对象,从而让我们能够调用一些方法来操作这些数据。 包装类型,是一个专门封装原始类型的值,并提供对原始类型的值执行操作的 API 对象


其他内置对象与基本包装类型对象的区别?


普通的内置对象与基本包装类型的主要区别就是对象的生命期,使用 new 操作符创建的引用类型的实例,在执行流离开当前作用域之前都一直保存在内存中,而自动创建的基本包装类型的对象,则只是存在于一行代码的执行瞬间,然后立即被立即销毁。这意味着我们不能再运行时为基本包装类型值添加属性和方法,也没有所谓的 constructor 了。


所以


console.log('a' instanceof String)//falseconsole.log(0 instanceof Number)//falseconsole.log(false instanceof Boolean)//falsenull 为一切对象的始祖


console.log(null instanceof null)


             ^
复制代码


TypeError: Right-hand side of 'instanceof' is not an object


其实对比起来,和 java 大同小异


转载本站文章《instanceof 运算符的实质:Java 继承链与 JavaScript 原型链》,请注明出处:https://www.zhoulujun.cn/html/webfront/ECMAScript/js/2015_1231_8493.html

发布于: 3 小时前阅读数: 3
用户头像

zhoulujun

关注

还未添加个人签名 2021.06.25 加入

还未添加个人简介

评论

发布
暂无评论
instanceof运算符的实质:Java继承链与JavaScript原型链