JavaScript 自己实现 instanceof

简介: JavaScript 自己实现 instanceof

介绍

Try it

instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。

function Car(make, model, year) {
  this.make = make;
  this.model = model;
  this.year = year;
}
const auto = new Car('Honda', 'Accord', 1998);

console.log(auto instanceof Car);
// expected output: true

console.log(auto instanceof Object);
// expected output: true

语法

object instanceof constructor

  • 参数
    object 某个实例对象
    constructor 某个构造函数
  • 描述
    instanceof 运算符用来检测 constructor.prototype 是否存在于参数 object 的原型链上。
// 定义构造函数
function C() {}
function D() {}

var o = new C();

o instanceof C; // true, 因为 Object.getPrototypeOf(o) === C.prototype

o instanceof D; // false, 因为 D.prototype 不存在于 o 的原型链上

o instanceof Object; // true, 因为 Object.prototype.isPrototypeOf(o) === true
C.prototype instanceof Object // true,同上

C.prototype = {};
var o2 = new C();

o2 instanceof C; // true

o instanceof C; // false , 因为 C.prototype 指向了一个空对象,这个对象不在 o 的原型链上

D.prototype = new C(); // 继承
var o3 = new D();
o3 instanceof D; // true
o3 instanceof C; // true
需要注意的是,如果表达式 obj instanceof Foo 返回 true,则并不意味着该表达式会永远返回 true,因为 Foo.prototype 属性的值有可能会改变。另外一种情况下,原表达式的值也会改变,就是改变对象 obj 的原型链的情况,虽然在目前的 ES 规范中,我们只能读取对象的原型而不能改变它,但借助于非标准的 __proto__ 伪属性,是可以实现的。

应用

检测对象是不是某个构造函数的实例

if (!(mycar instanceof Car)) {
  throw new Error('mycar is not an instance of Car');
}

实现

思路

  • 拿到当前类的原型,拿到实例对象的原型链
  • 沿着实例对象原型链,查找是否存在类的原型,直到尽头

    • 获取当前实例对象的原型,沿着原型链一直往上找
    • 如果在原型链上找到了类的原型,则返回 true
    • 如果直到 Object 的基类 null 都没有找到,则返回 false

代码

function myInstanceof (obj, constructor) {
  let proto = Object.getPrototypeOf(obj); // 实例对象的原型
  while (true) {
    if (proto === null) { // 到达尽头
      return false;
    }
    if (proto === constructor.prototype) { // 找到了
      return true;
    }
    proto = Object.getPrototypeOf(proto); // 沿着原型链继续找
  }
}
这里的 Object.getPrototypeOf(obj) 可以使用 obj.__proto__ 代替。但是推荐使用 Object.getPrototypeOf(obj),因为 __proto__ 已经被弃用了。
相关文章
|
3月前
|
JavaScript 前端开发
js确定数据类型typeof与instanceof
js确定数据类型typeof与instanceof
31 0
|
4月前
|
JavaScript
js【详解】instance of
js【详解】instance of
45 0
|
6月前
|
前端开发 JavaScript
前端 JS 经典:typeof 和 instanceof 区别
前端 JS 经典:typeof 和 instanceof 区别
119 0
|
6月前
|
JavaScript 前端开发
JavaScript中Object.prototype.toString.call()、instanceOf和Array.isArray()的区别
JavaScript中Object.prototype.toString.call()、instanceOf和Array.isArray()的区别
81 1
|
6月前
|
JavaScript 前端开发 测试技术
探究 JavaScript 类型检查的利器:typeof 和 instanceof
探究 JavaScript 类型检查的利器:typeof 和 instanceof
|
6月前
|
JavaScript 前端开发
JavaScript中Object.prototype.toString.call()、instanceOf和Array.isArray()的区别
JavaScript中Object.prototype.toString.call()、instanceOf和Array.isArray()的区别
|
11月前
|
JavaScript 前端开发
JavaScript学习(六十三)—typeof和instanceof检测数据类型的异同
JavaScript学习(六十三)—typeof和instanceof检测数据类型的异同
|
JavaScript
js基础笔记学习121-instanceOf
js基础笔记学习121-instanceOf
55 0
js基础笔记学习121-instanceOf
|
JavaScript 算法 前端开发
【前端算法】JS实现数字千分位格式化
JS实现数字千分位格式化的几种思路,以及它们之间的性能比较
349 1
|
存储 前端开发 算法
一行代码解决LeetCode实现 strStr()使用JavaScript解题|前端学算法
一行代码解决LeetCode实现 strStr()使用JavaScript解题|前端学算法
165 0
一行代码解决LeetCode实现 strStr()使用JavaScript解题|前端学算法