instanceof的功能和原理怎么理解,如何手动实现instanceof
Admin 2022-06-22 群英技术资讯 593 次浏览
instanceof
运算符用于检测构造函数的prototype
属性是否出现在某个实例对象的原型链上。
function Person() {} function Person2() {} const usr = new Person(); console.log(usr instanceof Person); // true console.log(usr instanceof Object); // true console.log(usr instanceof Person2); // false
如上代码,定义了两个构造函数,Person
和Person2
,又实用new
操作创建了一个Person
的实例对象usr
。
实用instanceof
操作符,分别检验构造函数的prototype
属性是否在usr
这个实例的原型链上。
当然,结果显示,Person
和Object
的prototype
属性在usr
的原型链上。usr
不是Person2
的实例,故Person2
的prototype
属性不在usr
的原型链上。
明白了instanceof
的功能和原理后,可以自己实现一个instanceof
同样功能的函数:
function myInstanceof(obj, constructor) { // obj的隐式原型 let implicitPrototype = obj?.__proto__; // 构造函数的原型 const displayPrototype = constructor.prototype; // 遍历原型链 while (implicitPrototype) { // 找到,返回true if (implicitPrototype === displayPrototype) return true; implicitPrototype = implicitPrototype.__proto__; } // 遍历结束还没找到,返回false return false; }
myInstanceof
函数接收两个参数:实例对象obj
和构造函数constructor
。
首先拿到实例对象的隐式原型:obj.__proto__
,构造函数的原型对象constructor.prototype
。
接着,就可以通过不断得到上一级的隐式原型:
implicitPrototype = implicitPrototype.__proto__;
来遍历原型链,寻找displayPrototype
是否在原型链上,若找到,返回true
。
当implicitPrototype
为null
时,结束寻找,没有找到,返回false
。
原型链其实就是一个类似链表的数据结构。
instanceof
做的事,就是在链表上寻找有没有目标节点。从表头节点开始,不断向后遍历,若找到目标节点,返回true
。遍历结束还没找到,返回false
。
写一个简单的实例验证一下自己实现的instanceof
:
function Person() {} function Person2() {} const usr = new Person(); function myInstanceof(obj, constructor) { let implicitPrototype = obj?.__proto__; const displayPrototype = constructor.prototype; while (implicitPrototype) { if (implicitPrototype === displayPrototype) return true; implicitPrototype = implicitPrototype.__proto__; } return false; } myInstanceof(usr, Person); // true myInstanceof(usr, Object); // true myInstanceof(usr, Person2); // false myInstanceof(usr, Function); // false myInstanceof(usr.__proto__, Person); // false usr.__proto__ instanceof Person; // false
可以看到,myInstanceof
正确得出了结果。
有趣的是,usr.__proto__ instanceof Person
返回false
,说明obj instanceof constructor
检测的原型链,不包括obj
节点本身。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
本篇文章给大家带来关于JavaScript中块级作用域的实现原理相关知识,在ES6之前,块级作用域是不被JavaScript所支持的,JavaScript是通过什么支持了块级作用域的呢?本文将讲解块级作用域的底层实现原理,希望对大家有帮助。
在vue3版本中,引入了一个新的函数,叫做setup。本文将通过实例为大家详细讲讲Vue3.2中setup语法糖的使用,感兴趣的小伙伴可以了解一下
用JS怎样实现类似淘宝tab切换栏的功能?tab切换栏的功能还是比较实用的,例如淘宝页面的商品详情,规格参数和累计评价三个栏,点击不同的栏下面出现的内容不同,这样的设计的好处就是能让页面更整洁美观,接下来我们就看看这个效果要怎样做。
相邻兄弟选择器是指在另一个元素之后可以选择的元素,两者具有相同的父元素。如需选择与另一元素紧密相连的元素,且两者具有相同的父元素,则可使用相邻兄弟选择器。
assert模块提供了简单的断言测试功能,主要用来内部使用,也可能require(‘assert’)后在外部进行使用。 assert模块的API为locked状态,也就是说,这个模块的API将不会再有添加或修改了。 Assert模块方法列表: assert(value[,message]) assert.deepEqual(actual
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008