【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() 进一步判断。
相关推荐
暮乘白帝过重山9 分钟前
Ollama 在本地分析文件夹中的文件
前端·chrome·ollama
一只小风华~23 分钟前
Web前端开发:CSS Float(浮动)与 Positioning(定位)
前端·css·html·html5·web
前端张三26 分钟前
vue3中ref在js中为什么需要.value才能获取/修改值?
前端·javascript·vue.js
moyu8427 分钟前
前端从后端获取数据的流程与指南
前端
爱的叹息1 小时前
解决 Dart Sass 的旧 JS API 弃用警告 的详细步骤和解决方案
javascript·rust·sass
涛哥码咖1 小时前
Rule.resourceQuery(通过路径参数指定loader匹配规则)
前端·webpack
夕水1 小时前
这个提升效率宝藏级工具一定要收藏使用
前端·javascript·trae
会飞的鱼先生2 小时前
vue3 内置组件KeepAlive的使用
前端·javascript·vue.js
斯~内克2 小时前
前端浏览器窗口交互完全指南:从基础操作到高级控制
前端
Mike_jia2 小时前
Memos:知识工作者的理想开源笔记系统
前端