instanceof 和 typeof 的区别与正确用法

更新日期: 2025-10-26 阅读: 217 标签: 区别

很多前端开发者经常困惑:什么时候该用 instanceof,什么时候该用 typeof?这两个操作符看起来都用于类型检查,但它们的用途和原理完全不同。


快速了解基本语法

instanceof 的语法很简单:

object instanceof Constructor  // 返回 true 或 false

左边是要检查的对象,右边是构造函数。简单说,就是检查对象是否属于某个构造函数的实例。

typeof 的用法更直接:

typeof value  // 返回类型字符串


instanceof 的工作原理:查找原型链

instanceof 的核心是检查对象的原型链。它的工作流程是这样的:

  1. 获取对象的原型:Object.getPrototypeOf(obj)

  2. 获取构造函数的原型属性:Constructor.prototype

  3. 沿着原型链向上查找,直到:

    • 找到匹配的原型 → 返回 true

    • 找到 null 还没有匹配 → 返回 false

代码来模拟这个过程:

function instanceOf(obj, Ctor) {
  if (typeof obj !== 'object' || obj === null) return false;
  let proto = Object.getPrototypeOf(obj);
  while (proto) {
    if (proto === Ctor.prototype) return true;
    proto = Object.getPrototypeOf(proto);
  }
  return false;
}


实际例子理解原型链

假设我们有这样的继承关系:

function Animal() {}
function Dog() {}
Dog.prototype = Object.create(Animal.prototype);

const d = new Dog();

原型链是这样的:

d → Dog.prototype → Animal.prototype → Object.prototype → null

检查结果:

d instanceof Dog      // true,第一层匹配
d instanceof Animal   // true,第二层匹配  
d instanceof Object   // true,第三层匹配
d instanceof Cat      // false,整个链都没有 Cat.prototype


instanceof 的常见问题

1. 原始类型返回 false

"abc" instanceof String   // false
123 instanceof Number     // false
true instanceof Boolean   // false

只有使用 new 创建的包装对象才会返回 true:

new String('abc') instanceof String   // true

2. 跨框架问题

在不同 iframe 或窗口中,相同的构造函数会有不同的原型:

// 在 iframe A 中
const iframeArray = window.frames[0].Array;
const arr = [];
arr instanceof Array           // true
arr instanceof iframeArray     // false

3. 修改 prototype 的影响

function F() {}
const o = new F();
F.prototype = {};     // 修改了原型
console.log(o instanceof F); // false

4. 自定义 instanceof 行为

ES6 引入了 Symbol.hasInstance,可以自定义 instanceof 的行为:

class MyArray {
  static [Symbol.hasInstance](obj) {
    return Array.isArray(obj) && obj.length > 3;
  }
}

[1,2,3,4] instanceof MyArray; // true
[1,2] instanceof MyArray;     // false


instanceof 与 typeof 对比

typeof 结果instanceof 检查说明
[]'object'Arraytypeof 无法区分数组和对象
{}'object'Object同上
new String('')'object'String包装对象
function fn(){}'function'Functiontypeof 能识别函数
null'object'任何都是 falseJavaScript 的历史问题
"hello"'string'String → false原始类型

实际应用:安全的类型检查

检查数组的推荐方法

// 不推荐的方法
const isArray = value => value instanceof Array;

// 推荐的方法
const isArray = value => Array.isArray(value);

Array.isArray() 比 instanceof 更好,因为它:

  • 性能更好

  • 解决跨框架问题

  • 代码意图更清晰

实用的类型检查函数

function getType(value) {
  // 先处理 null
  if (value === null) return 'null';
  
  // 处理其他类型
  const type = typeof value;
  if (type !== 'object') return type;
  
  // 详细的对象类型检查
  if (Array.isArray(value)) return 'array';
  if (value instanceof Date) return 'date';
  if (value instanceof RegExp) return 'regexp';
  
  return 'object';
}


使用建议和最佳实践

1. 基础类型检查用 typeof

// 检查是否是字符串
if (typeof value === 'string') {
  // 处理字符串
}

// 检查是否是函数
if (typeof callback === 'function') {
  callback();
}

2. 对象类型检查用 instanceof

// 检查是否是日期对象
if (value instanceof Date) {
  console.log(value.getFullYear());
}

// 检查是否是自定义类的实例
if (employee instanceof Manager) {
  employee.approveRequest();
}

3. 特殊情况的处理

// 处理 null 和 undefined
if (value == null) {
  // 同时处理 null 和 undefined
}

// 安全的属性访问
if (typeof obj?.property === 'string') {
  // 使用可选链避免错误
}


常见误区避免

不要用 instanceof 检查原始类型

// 错误
if (value instanceof String) {
  // 这只会对 new String('') 返回 true
}

// 正确
if (typeof value === 'string') {
  // 对字符串字面量和 String 对象都有效
}

注意构造函数的变化

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

const user1 = new User('张三');
User.prototype = {};  // 修改原型
const user2 = new User('李四');

console.log(user1 instanceof User); // false
console.log(user2 instanceof User); // true


进阶技巧

实现多重继承检查

class Animal {}
class Flyable {
  static [Symbol.hasInstance](obj) {
    return typeof obj.fly === 'function';
  }
}

class Bird extends Animal {
  fly() {}
}

const bird = new Bird();
console.log(bird instanceof Animal);  // true
console.log(bird instanceof Flyable); // true

安全的类型判断函数

function safeTypeCheck(value, type) {
  if (typeof type === 'function') {
    return value instanceof type;
  }
  
  switch (type) {
    case 'array': return Array.isArray(value);
    case 'null': return value === null;
    case 'undefined': return value === undefined;
    default: return typeof value === type;
  }
}


总结

记住这几个要点:

  1. typeof 用于检查原始类型和函数,返回类型字符串

  2. instanceof 用于检查对象是否是某个构造函数的实例,检查原型链

  3. 原始类型 用 typeof 检查,对象类型用 instanceof 检查

  4. 跨框架 时使用 Array.isArray() 等内置方法

  5. 注意原型修改 对 instanceof 结果的影响

在实际开发中,根据具体需求选择合适的类型检查方法。对于基础类型,typeof 更合适;对于复杂的对象类型,instanceof 更准确。理解它们的原理和差异,能帮助你写出更健壮的代码。

本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!

链接: https://fly63.com/article/detial/13053

相关推荐

AR / MR / VR / XR有什么区别?

VR能让人完全沉浸在虚拟环境中;AR能创建一个叠加在虚拟内容的世界,但不能与真实环境交互; MR则是虚拟与现实的混合体,它能创造出可以与真实环境交互的虚拟物体。最后,XR则是包括三种“现实”(AR,VR,MR)的术语。

Js插件、 组件、类库、框架的区别

框架和类库等概念的出现都是源于人们对复用的渴望。“不要重复发明轮子”,成了软件界的一句经典名言。从最初的单个函数源代码的复用,到面向对象中类的复用(通常以类库的形式体现)

理解screenX,clientX,pageX,offsetX,pageXoffset的区别

event.screenX、event.screenY鼠标相对于用户显示器屏幕左上角的X,Y坐标。标准事件和IE事件都定义了这2个属性,event.clientX、event.clientY鼠标相对于浏览器可视区域的X,Y坐标

初中高级工程师的区别?

我们知道程序员分 初级,中级, 高级, 这个概念, 并不是以工作年限作为分类依据的。 也就是说, 级别和你工作多少年没有必然的联系。一个初级工程师可能工作很多年依然是初级工程师, 也有的工程师, 工作短短两三年, 就跻身高级工程师的行列。

互联网、局域网、万维网三者区别?

互联网是指多台设备(如计算机、手机等)通过特定通信协议(TCP/IP、IPX/SPX、NetBIOS、NetBEUI、Apple Talk)组成的网络。一般可分为以下三种:局域网LAN(Local Area Network):一般不大于10公里,而且通常只使用一种传输介质

js中.和[]的区别

在js中,对象属于是键值对的集合,在上面这个代码中,name就属于是key,而‘残梦‘就是value。总之一句话: []更强大,.就是用起来更加习惯一些,一开始用[]的时候总是会当成数组,需要注意一下

CSS中zoom和scale的差异

zoom和scale这两个东西都是用于对元素的缩放,但两者除了兼容性之外还有一些不同的地方。zoom缩放会将元素保持在左上角,而scale默认是中间位置,可以通过transform-origin来设置。

*.min.js跟*.js的区别

js是JavaScript 源码文件, .min.js是压缩版的js文件。减小体积 .min.js文件经过压缩,相对编译前的js文件体积较小,传输效率快。防止窥视和窃取源代码

package.json中^和~的区别

webpack 项目的package.json 文件列出了项目所依赖的插件和库,同时也给出了对应的版本说明,但是在版本说明前面还有个符号:‘^‘(插入符号)和‘~‘(波浪符号),总结了下他们之间的区别:

PTN与SDH的区别?

SDH是基于TDM技术,主要用于传输语音,此外采用GFP封装来传输IP包,物理介质为光纤。PTN是采用DWDM技术,主要用于传输IP包、以太网帧,此外采用MPLS-TP技术来实现PWE3伪线

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!