前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JS 手写: instanceof

JS 手写: instanceof

作者头像
Cellinlab
发布2023-05-17 15:16:19
3440
发布2023-05-17 15:16:19
举报
文章被收录于专栏:Cellinlab's BlogCellinlab's Blog

# 介绍

# Try it

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

代码语言:javascript
复制
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 的原型链上。
代码语言:javascript
复制
// 定义构造函数
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__ 伪属性,是可以实现的。

# 应用

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

代码语言:javascript
复制
if (!(mycar instanceof Car)) {
  throw new Error('mycar is not an instance of Car');
}

# 实现

# 思路

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

# 代码

代码语言:javascript
复制
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__ 已经被弃用了。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021/1/3,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • # 介绍
    • # Try it
      • # 语法
        • # 应用
        • # 实现
          • # 思路
            • # 代码
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档