Skip to main content

实现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);
}

}

参考