【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() 进一步判断。
相关推荐
永日456704 分钟前
学习日记-HTML-day51-9.9
前端·学习·html
狗头大军之江苏分军20 分钟前
iPhone 17 vs iPhone 17 Pro:到底差在哪?买前别被忽悠了
前端
小林coding21 分钟前
再也不怕面试了!程序员 AI 面试练习神器终于上线了
前端·后端·面试
wjm04100623 分钟前
ios面试八股文
ios·面试
文心快码BaiduComate33 分钟前
WAVE SUMMIT深度学习开发者大会2025举行 文心大模型X1.1发布
前端·后端·程序员
babytiger33 分钟前
python 通过selenium调用chrome浏览器
前端·chrome
passer98140 分钟前
基于webpack的场景解决
前端·webpack
华科云商xiao徐1 小时前
Java并发编程常见“坑”与填坑指南
javascript·数据库·爬虫
知其然亦知其所以然1 小时前
面试官微笑发问:第100万页怎么查?我差点当场沉默…
后端·mysql·面试