// 方法一:
// 变量 R 的原型是否存在于变量 L 的原型链上;
function instance_of(L, R) {
// 若变量 R 为基本数据类型,直接返回 false
const baseType = ['string', 'number', 'boolean', 'undefined', 'symbol']
if(baseType.includes(typeof(L))) return false;
let RP = R.prototype; // 取 R 的显示原型
L = L.__proto__; // 取 L 的隐式原型
while(true) {
if(L === null) return false; // 此时找到最顶层了
if(L === RP) return true;
L = L.__proto__; // 没找到时,继续向上一层原型链查找
}
}
console.log(instance_of({}, Object))
// 方法二:
function myInstanceof(L, R) {
// 若变量 R 为基本数据类型,直接返回 false
const baseType = ['string', 'number', 'boolean', 'undefined', 'symbol']
if(baseType.includes(typeof(L))) return false;
// 获取实例对象原型
let proto = Object.getPrototypeOf(L);
// 获取构造函数的 prototype 对象
let prototype = R.prototype;
// 判断构造函数 R 的 prototype 对象是否在对象 L 的原型链上
while(true) {
if (!proto) return false
if (proto === prototype) return true
// 如果没有找到,就继续从其原型上找
// Object.getPrototypeOf方法用来获取指定对象的原型(内部[[Prototype]]属性的值)
proto = Object.getPrototypeOf(proto);
}
}
console.log(myInstanceof('', Object))
解析如下代码,证明 万物皆对象:
function Foo(name) {
this.name = name;
}
var f = new Foo('chen');
f instanceof Foo; // true
f instanceof Object; // true
上述代码的判断流程大致如下:
f instanceof Foo
:f
的隐式原型__proto__
和Foo.prototype
是相等的,所以返回true
;f instanceof Object
:f
的隐式原型__proto__
和Object.prototype
是不等的,所以继续往上走。f
的隐式原型__proto__
指向Foo.prototype
,所以继续用Foo.prototype.__proto__
去对比Object.prototype
,此时是相等的,因为Foo.prototype
就是一个普通的对象。