1. instanceof的用法instanceof 运算符用于检测构造函数的prototype 属性是否出现在某个实例对象的原型链上。
function Person() {}function Person2() {}const usr = new Person();console.log(usr instanceof Person); // trueconsole.log(usr instanceof Object); // trueconsole.log(usr instanceof Person2); // false 如上代码,定义了两个构造函数,Person 和Person2 ,又实用new 操作创建了一个Person 的实例对象usr 。 实用instanceof 操作符,分别检验构造函数的prototype 属性是否在usr 这个实例的原型链上。 当然,结果显示,Person 和Object 的prototype 属性在usr 的原型链上。usr 不是Person2 的实例,故Person2 的prototype 属性不在usr 的原型链上。 2. 实现instanceof明白了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 。
3. 验证写一个简单的实例验证一下自己实现的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); // truemyInstanceof(usr, Object); // truemyInstanceof(usr, Person2); // falsemyInstanceof(usr, Function); // falsemyInstanceof(usr.__proto__, Person); // falseusr.__proto__ instanceof Person; // false 可以看到,myInstanceof 正确得出了结果。 有趣的是,usr.__proto__ instanceof Person 返回false ,说明obj instanceof constructor 检测的原型链,不包括obj 节点本身。 JavaScript常见手写代码: 「GitHub 下载地址: Vue实现跑马灯简单效果 js数组的 entries() 获取迭代方法 |