// 方法一:// 变量 R 的原型是否存在于变量 L 的原型链上;function instance_of(L, R) {// 若变量 R 为基本数据类型,直接返回 falseconst 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 为基本数据类型,直接返回 falseconst 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 falseif (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; // truef 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就是一个普通的对象。
