实现instanceof
一、题意
实现一个instanceof,补全TODO部分
function newInstanceOf (leftValue, rightValue) {
// TODO
}
测试用例
const a = [];
const b = {};
function Foo () {}
var c = new Foo()
function Child () {}
function Father() {}
Child.prototype = new Father()
var d = new Child()
console.log(newInstanceOf(a, Array)) // true
console.log(newInstanceOf(b, Object)) // true
console.log(newInstanceOf(b, Array)) // false
console.log(newInstanceOf(a, Object)) // true
console.log(newInstanceOf(c, Foo)) // true
console.log(newInstanceOf(d, Child)) // true
console.log(newInstanceOf(d, Father)) // true
console.log(newInstanceOf(123, Object)) // false
console.log(123 instanceof Object) // false
二、背景知识
__proto__
__proto__
属性是一个访问器属性(一个getter函数和一个setter函数), 暴露了通过它访问的对象的内部[[Prototype]]
(一个对象或 null)。
虽然ES6兼容该属性,但是官方不推荐使用
Object.getPrototypeOf()
**Object.getPrototypeOf()**
方法返回指定对象的原型(内部[[Prototype]]
属性的值)
instanceof
instanceof
运算符用于检测构造函数的 prototype
属性是否出现在某个实例对象的原型链上。
注意
只有函数才有prototype
属性
二、解法
// leftValue为实例,rightValue为构造函数
function newInstanceOf (leftValue, rightValue) {
// leftValue不是对象,则不存在继承
if(typeof leftValue !== 'object'){
return false;
}
// 取出构造函数rightValue的prototype
const rightPrototype = rightValue.prototype;
// 取出实例的原型
let leftPrototype = Object.getPrototypeOf(leftValue);
while(true){
// 如果原型为null,则代表已经遍历完原型链,没匹配到
if(leftPrototype === null){
return false;
}
if(leftPrototype === rightPrototype){
return true;
}
// 如果原型不相等,则继续在原型链上查找
leftPrototype = Object.getPrototypeOf(leftPrototype);
}
}