1 手写实现instanceof函数
instanceof 是 JavaScript 中的一个运算符,用于检测一个对象是否是某个构造函数的实例。它的语法是 object instanceof Constructor,如果 object 是 Constructor.prototype 的一个实例,返回 true,否则返回 false。
简易实现步骤:
- 获取到对象__proto__
- 如果对象__proto__存在,则判断constuctor的prototype是否和__proto__相等,相等的话函数返回true
- 不相等的话继续沿原型链向上查找proto = proto
- 直到proto为空,返回false
极简版手写instanceof函数
自己实现的出版代码如下,大家自己想想有什么问题?
javascript
const Myinstanceof = (obj, constructor) => {
let proto = obj.__proto__
while(proto){
if(proto === constructor.prototype){
return true
}
proto = proto.__proto__
}
return false
}
优化版手写instanceof函数
有以下问题:
-
未检查 obj 是否为对象或函数
-
未检查 constructor 是否为函数
-
通过__proto__获得obj原型链上的对象不一定可用,Object.getPrototypeOf 获取 obj 的原型对象是官方给出的方法
修改后的代码如下所示:
javascript
const MyGoinstanceof = (obj, constructor) => {
// 检查 obj 是否为对象或函数
if (obj == null || (typeof obj !== 'object' && typeof obj !== 'function')) {
return false;
}
// 检查 constructor 是否为函数
if (typeof constructor !== 'function') {
return false;
}
let proto = Object.getPrototypeOf(obj);
while (proto) {
if (proto === constructor.prototype) {
return true;
}
proto = Object.getPrototypeOf(proto);
}
return false;
}
测试代码如下所示:
javascript
function test(){
}
const obj = new test()
console.log(Myinstanceof(obj, test)) // true
console.log(obj instanceof test) // true
console.log("--------------------")
console.log(Myinstanceof(obj, Object)) // true
console.log(obj instanceof Object) // true
console.log("--------------------")
console.log(Myinstanceof(obj, Array)) // false
console.log(obj instanceof Array) // false
console.log("--------------------")
console.log(Myinstanceof([], Array)) // true
console.log([] instanceof Array) // true
console.log("--------------------")
console.log(Myinstanceof([], Object)) // true
console.log([] instanceof Object) // true
console.log("--------------------")
console.log(MyGoinstanceof(undefined, Object)) // false
console.log(undefined instanceof Object) // false
console.log("--------------------")
console.log(MyGoinstanceof(null, Object)) // false
console.log(null instanceof Object) // false
console.log("--------------------")
console.log(MyGoinstanceof({}, function(){})) // false
console.log({} instanceof function(){}) // false
console.log("--------------------")
console.log(MyGoinstanceof({}, 1)) // TypeError: Right-hand side of 'instanceof' is not callable
2 判断数组的方法
- 使用Array.prototype.isArray() Array类上的静态方法。
- 使用1中提到的instanceof方法 instanceof Array。
- 使用对象上的constructor方法判断,其指向构造函数 arr.constuctor === Array。
- 使用Object.prototype.toString.call(array) 判断是否等于字符串"[object Array]"
四种实现方式代码验证如下所示:
javascript
// 判断数组的方法
// Array.isArray
const arr = []
console.log(Array.isArray(arr))
// instanceof Array
console.log(arr instanceof Array)
// constructor
console.log(arr.constructor === Array)
// Object.prototype.toString.call
console.log(Object.prototype.toString.call(arr) === '[object Array]')