1.instanceof:
instanceof 是用来检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。例如:
function A() {} function B() {} let a = new A() a instanceof A // true ,因为Object.getPrototypeOf(a) === A.prototype。 a instanceof B // false, 因为B.prototype 不在a的原型链上。 a instanceof Object // true, 因为Object.prototype.isPrototypeOf(a) = true。
复制
但是 instanceof 也存在缺陷,就是它不能精确的判断 Object 类的具体数据类型。例如:
[] instanceof Array; // true, Object.getPrototypeOf([]) === Array.prototype function A() {}; let a = new A(); a instanceof A ; // true,同上 [] instanceof Object; // true, 这是什么原因呢? a instanceof Object; // true, 这是什么原因呢?
复制
从上面的例子我们可以发现 [ ] 通过 instanceof 可以判断出其实 Array 的实例对象,但是不能辨别 [ ] 不是 Object 的实例对象,通过构造函数也是这个效果,造成这样的原因:主要与原型链有关:[ ].__proto__ 指向的是 Array.prototype,而 Array.prototype.__proto__ 指向的是 Object.prototype,Object.prototype.__proto__ 指向了 null。同理 a.__proto__ 指向的是Function.prototype,而Function.prototype.__proto__ 指向了 Object.prototype。
2. 原理实现:
function _instanceof(E, C){ let c = C.prototype; let e = E.__proto__; while(true){ if(e === null){ return false } if(e === c) { return true } e = e.__proto__ } } let arr = [] console.log(__instanceof(arr, Array)) // true
复制
总结:综上所述,其实发现instanceof其实就是原型链的一个查找过程。
3.判断类型的通用方法:
function typesof(type) { let typeList = {}; ['Boolean','Number','String','Function','Array','Date','RegExp','Object','Error','Symbol'].forEach((item) => { typeList[`[object ${item}]`] = item.toLowerCase(); }); if (type == null) { return type + ""; } if (typeof type === "object" || typeof type === "function") { return typeList[toString.call(type)] || "object"; } else { return typeof type; } } console.log(typesof([])); // 'array' console.log(typesof(123)); // 'number' console.log(typesof("123")); // 'string' console.log(typesof({})); // 'object' console.log(typesof(true)); // 'boolean' console.log(typesof(Symbol())); // 'symbol' console.log(typesof(new Date())); // 'date' console.log(typesof(new RegExp())); // 'regexp' console.log(typesof(new Error())); // 'error' console.log(typesof(function a(){})); // 'function'
复制