【JS】instanceof 和 typeof 的使用

instanceoftypeof

instanceof

instanceof 用于检查一个对象是否是某个构造函数的实例。换句话说,它会检查对象的原型链上是否存在该构造函数的 prototype 属性。 示例代码

js 复制代码
let a = new Number(1)
console.log(a instanceof Number);  // true
console.log(a.__proto__.constructor === Number) // true
console.log(a.__proto__ === Number.prototype) // true
console.log('------')
let b = 1
console.log(b instanceof Number); // false
console.log(b.__proto__.constructor === Number) // true
console.log(b.__proto__ === Number.prototype) // true (临时包装对象)

按照上面的说法
x instanceof Y 检查 x 的原型链上是否有 Y.prototype

可以等效为 x.__proto__ === Y.prototype (但是又不完全等效,因为instanceof会在整个原型链上递归查找)

如果我们仅看这个简单的等效,对比上面的4、9行代码。

a是对象 ,b是原始类型 。严格来说,原始类型是没有__proto__的,但是JS引擎会在访问他们的属性的时候,临时包装成对象,使其看起来有__proto__,所以在第9行,还是会输出 true

所以这里为什么第7行,输出是false呢,不是按照上面的规则来,就检查x.__proto__ === Y.prototype 吗,既然第9行为true,但是第7行为false呢?

这里就涉及到另外一条规则了,如果x是原始类型,那么会直接返回false,因为原始类型没有原型链,上面的第9行是包装之后才有了原型链。

工作原理

x instanceof Y 的完整行为:

  1. 如果 x 是原始类型(如 1, "a", true),直接返回 false(因为原始类型没有原型链)。
  2. 如果 x 是对象,则沿着 x 的原型链向上查找,检查是否有 Y.prototype
    • 先检查 x.__proto__ === Y.prototype,如果是,返回 true
    • 如果不是,继续检查 x.__proto__.__proto__ === Y.prototype,依此类推,直到原型链尽头(null)。
js 复制代码
class Animal {}
class Dog extends Animal {}

const dog = new Dog();
console.log(dog instanceof Dog);     // true
console.log(dog instanceof Animal);  // true(因为 Dog 继承 Animal)
console.log(dog instanceof Object);  // true(所有对象最终继承 Object)

typeof

用来返回变量的基本类型,以字符串的形式返回,且不会检查原型链

js 复制代码
console.log(typeof 42);           // "number"
console.log(typeof "hello");      // "string"
console.log(typeof true);         // "boolean"
console.log(typeof undefined);    // "undefined"
console.log(typeof null);         // "object"(历史遗留 bug)
console.log(typeof {});           // "object"
console.log(typeof []);           // "object"(数组也是对象)
console.log(typeof function() {}); // "function"
console.log(typeof Symbol());     // "symbol"
console.log(typeof 123n);         // "bigint"

其中数组、对象、null都会被判断为object。函数也是对象,但是typeof对其进行了特殊处理,返回了function。

  • typeof null === "object"
    这是 JavaScript 早期的一个 Bug,但由于历史原因无法修复。
  • typeof [] === "object"
    数组本质是对象,无法直接区分数组和普通对象(可以用 Array.isArray() 判断)。
  • typeof function() {} === "function"
    函数虽然是对象,但 typeof 对其特殊处理,返回 "function"

总结

操作符 适用场景 不适用场景
typeof 检查原始类型、undefinedfunction 无法区分对象的具体类型(如数组 vs 普通对象)
instanceof 检查对象是否是某个类的实例(包括继承) 不适用于原始类型

推荐组合使用:

  • typeof 判断是否是原始类型。
  • 如果是对象,再用 instanceofArray.isArray() 进一步判断。
相关推荐
知识分享小能手8 分钟前
uni-app 入门学习教程,从入门到精通,uni-app 基础知识详解 (2)
前端·javascript·windows·学习·微信小程序·小程序·uni-app
文心快码BaiduComate17 分钟前
限时集福!Comate挂件/皮肤上线,符(福)气掉落中~
前端·后端·程序员
勇敢di牛牛17 分钟前
vue3 + mars3D 三分钟画一个地球
前端·vue.js
ssshooter1 小时前
MCP 服务 Streamable HTTP 和 SSE 的区别
人工智能·面试·程序员
IT_陈寒1 小时前
Python+AI实战:用LangChain构建智能问答系统的5个核心技巧
前端·人工智能·后端
DIY机器人工房1 小时前
【嵌入式面试题】STM32F103C8T6 完整元器件解析 + 面试问题答案
stm32·单片机·面试·嵌入式·面试题·diy机器人工房
袁煦丞2 小时前
MoneyPrinterTurbo一键生成短视频:cpolar内网穿透实验室第644个成功挑战
前端·程序员·远程工作
代码小学僧2 小时前
让 AI 真正帮你开发:前端 MCP 实用技巧分享
前端
晴殇i2 小时前
前端鉴权新时代:告别 localStorage,拥抱更安全的 JWT 存储方案
前端·javascript·面试
来旺2 小时前
互联网大厂Java面试全解析及三轮问答专项
java·数据库·spring boot·安全·缓存·微服务·面试