JavaScript instanceof:你真的懂它吗?

什么是 instanceof

instanceof 运算符用于检测构造函数的 prototype 属性是否出现在对象的原型链中的任何位置。简单来说,它判断一个对象是否是某个构造函数的实例。

语法:

javascript 复制代码
object instanceof constructor
  • object: 要检测的对象。
  • constructor: 构造函数。

返回值:

  • 如果 objectconstructor 的实例,则返回 true
  • 否则,返回 false

示例:

javascript 复制代码
function Person(name) {
  this.name = name;
}

const person = new Person("Alice");

console.log(person instanceof Person); // true
console.log(person instanceof Object); // true (因为 Person 的原型链最终指向 Object)
console.log(person instanceof Array);  // false

instanceof 对比 typeof

typeof 只能区分基本数据类型(string, number, boolean, undefined, symbol)和 object。对于对象类型,typeof 只能返回 object,无法区分是数组、日期、还是自定义对象。而 instanceof 可以更精确地判断对象的类型,因为它会沿着原型链向上查找。

javascript 复制代码
const arr = [];
const date = new Date();

console.log(typeof arr);  // object
console.log(typeof date); // object
console.log(typeof null); // object (这是一个历史遗留问题,需要注意)

instanceof 的工作原理:原型链的秘密

instanceof 的核心在于原型链。每个 JavaScript 对象都有一个指向其原型的链接,这个原型本身也是一个对象,也有自己的原型,以此类推,形成一个原型链。

当使用 instanceof 运算符时,JavaScript 引擎会:

  1. 获取 constructorprototype 属性。
  2. 沿着 object 的原型链向上查找。
  3. 如果找到与 constructor.prototype 相等的原型,则返回 true
  4. 如果直到原型链的顶端(null)都没有找到,则返回 false

手写一个 myInstanceOf 函数:

为了更好地理解 instanceof 的工作原理,我们可以尝试手写一个类似的函数:

javascript 复制代码
function myInstanceOf(obj, constructor) {
  if (typeof obj !== 'object' || obj === null) {
    return false; // 基本类型和 null 不是任何构造函数的实例
  }

  let proto = Object.getPrototypeOf(obj); // 获取对象的原型

  while (proto) {
    if (proto === constructor.prototype) {
      return true;
    }
    proto = Object.getPrototypeOf(proto); // 继续向上查找原型链
  }

  return false; // 没有找到
}

function Person(name) {
  this.name = name;
}

const person = new Person("Alice");

console.log(myInstanceOf(person, Person)); // true
console.log(myInstanceOf(person, Object)); // true
console.log(myInstanceOf(person, Array));  // false
相关推荐
当时只道寻常3 分钟前
Vue3 集成 NProgress 进度条:从入门到精通
前端·vue.js
kyriewen4 分钟前
React性能优化:从“卡成狗”到“丝般顺滑”的5个秘诀
前端·react.js·性能优化
米丘4 分钟前
Vue 3.x 单文件组件(SFC)模板编译过程解析
前端·vue.js·编译原理
helloweilei6 分钟前
Web Streams 简介
前端·javascript
悟空瞎说6 分钟前
Flutter热更新 Shorebird CodePush 原理、实现细节及费用说明
前端·flutter
didadida2627 分钟前
从“不存在”的重复请求,聊到 Web 存储的深坑
前端
xiaominlaopodaren8 分钟前
Three.js 渲染原理-透明渲染为什么这么难
前端
米丘9 分钟前
vue3.x 内置指令有哪些?
前端·vue.js
米丘10 分钟前
Vue 3.x 模板编译优化:静态提升、预字符串化与 Block Tree
前端·vue.js·编译原理
一川_11 分钟前
前端驱动工业报警:基于 WebSocket 与网关的三色蜂鸣灯实时报警系统实战
javascript·websocket