JavaScript中的intanceof 如何实现

444 阅读2分钟

本文已参与「 新人创作礼 」活动,一起开启掘金创作之路

关于如何进行图片优化 - 适合的才是最好的

在前端开发的学习中, prototype,是我们一直要去攻克的难题。

前端所有的对象构造,伪class , new 都是通过prototype 进行操作实现的。

平时我们项目开发中, 对于prototype其实应用并不多,因为我们大部分都是用到util包来处理的。

特别是intanceof 可以用来比较复杂数据类型。

举例说明下:

我们来举例说明说明下 intanceof 

/aa/g instanceof Object   true

/aa/g instanceof RegExp  true

一切对象的base Object 为 Object,看似比较拗口,也就是RegExp 的 prototype 指向的就是Object。

let a1 = Object.getPrototypeOf(/aa/g)  

getProtypeOf是Object对象自带的API,能够拿到参数的原型对象

let a1 = Object.getPrototypeOf(/aa/g)  
a1 === RegExp.prototype

这里的a1 就是指向复杂对象RegExp的原型 ,也就是就是instance 比较为true

但是

a1 === Object.prototype   还是false

这个时候我们还需要沿着链继续往上寻找

代码为

let a2 = Object.getPrototypeOf(a1)  
a2 === Object.prototype 这个时候就为true

但是如何写一个比较通过的数数据比较呢 ? 

function myInstanceof(left, right) {
  // 这里先用typeof来判断基础数据类型,如果是,直接返回false
  if(typeof left !== 'object' || left === null) return false;
  let proto = Object.getPrototypeOf(left);
  while(true) { //循环往下寻找,直到找到相同的原型对象
    if(proto === null) return false;
    if(proto === right.prototype) return true;//找到相同原型对象,返回true
    proto = Object.getPrototypeof(proto);
  }
}
// 验证一下自己实现的myInstanceof是否OK
console.log(myInstanceof(new Number(123), Number));// true

这里面有几个知识点,其实主要就是要了解原型的查找,以及如何获取原型。

接下来我们说下prototype在链上的对应关系。prototype、getPrototypeOf和__proto__ 直接的对应关系。

例如我们大致举例说明下

function fnA (a,b){this.dang = a;this.xia = b}
let a = new fnA('wan' , 'ali')
fnA.prototype.toString = function() {
  return '[aaaa ' + this.dang + ']';
}
console.log(Object.getPrototypeOf(a)); // fnA {toString: ƒ, constructor: ƒ}

console.log(a.__proto__); // fnA  {toString: ƒ, constructor: ƒ}
console.log(fnA.prototype); // fnA {toString: ƒ, constructor: ƒ}

这几个是获取方式,他们之间又是如何关联的呢 ? 

有时间我好好再来说道一番。

PS:学习前端一定要一步步的来,要有锲而不舍的精神,把所有的东西一步步学扎实。基础知识枯燥乏味,但是对于你对前端的深刻理解有着非常的重要。