13、✅ 手写 instanceof、typeof、Object.prototype.toString,搞清 JS 类型判断机制

🎯 一、为什么要掌握这三种类型判断?

在开发和面试中你一定遇到过:

判断方式 优点 缺点
typeof 快速判断原始类型 对对象不准,如 typeof null === 'object'
instanceof 判断引用类型关系 对基本类型无效,跨 iframe 不准
Object.prototype.toString.call 最精确的方式 写法繁琐,需背模板

掌握这些是 JS 基础能力的核心体现,也是面试官常考点。


📌 二、类型判断原理总览

方法 原理 常见用途
typeof 内部通过 typeof 操作符返回固定字符串 判断基本类型
instanceof 判断 原型链 上是否存在构造函数的 prototype 判断对象与类的继承关系
toString.call() 利用对象内部的 [[Class]] 判断所有对象准确类型

✍️ 三、手写 instanceof

我们已在第 3 篇中写过,这里复习:

ini 复制代码
function myInstanceof(obj, Constructor) {
  if (obj == null || typeof obj !== 'object') return false;

  let proto = Object.getPrototypeOf(obj);
  const prototype = Constructor.prototype;

  while (proto) {
    if (proto === prototype) return true;
    proto = Object.getPrototypeOf(proto);
  }

  return false;
}

✅ 四、手写 typeof(本质:操作符,不可完全重写)

typeof 是语言级别保留的操作符,不能被完全手写模拟,但可以封装一个更强的类型判断函数来补足它的不足:

javascript 复制代码
function getType(val) {
  return typeof val === 'object'
    ? val === null
      ? 'null'
      : Object.prototype.toString.call(val).slice(8, -1).toLowerCase()
    : typeof val;
}

✅ 示例:

scss 复制代码
getType(123); // 'number'
getType(null); // 'null'
getType([]); // 'array'
getType(() => {}); // 'function'
getType(Symbol('x')); // 'symbol'

✍️ 五、手写 Object.prototype.toString.call 封装

javascript 复制代码
function toRawType(val) {
  return Object.prototype.toString.call(val).slice(8, -1); // 输出大写首字母格式:Array/Object/Date...
}

示例:

scss 复制代码
toRawType([]); // "Array"
toRawType(null); // "Null"
toRawType(new Date()); // "Date"
toRawType(/\d+/); // "RegExp"

🧠 六、对比总结(面试必背)

方法 可判断基本类型 可判断对象类型 可判断数组 能准确区分 null 跨 iframe 准确性
typeof ❌ (typeof null === 'object')
instanceof ❌(不同 iframe 的 Array/Function 不一样)
Object.prototype.toString.call
相关推荐
Emily1568535987042 分钟前
Emerson 1C31129G03 Analog Input Module
java·开发语言·前端·plc·emerson·1c31129g03·input module
To_OC6 小时前
面试被问了三回三栏布局,这次我终于把 BFC 那层窗户纸捅破了
前端·css·面试
To_OC6 小时前
啃完 TS 工具类型我发现:Pick 和 Omit 原来就是一层窗户纸
前端·面试·typescript
风月说与山鬼7 小时前
三、大括号语法
前端·react.js
kyriewen8 小时前
我把最常踩的8个CORS跨域报错整理了一遍——第8个去年还不存在
前端·javascript
Csvn8 小时前
🕰️ 闭包 + setTimeout 的 5 个经典陷阱:为什么定时器看到的永远不是最新的值?
前端
lilian2339 小时前
Harmony os 技术实战|拼豆制图27:用单字符编码承载 50 张 70×70 图纸
前端·数据库·华为·harmonyos
CarIise9 小时前
CSS选择器与样式关联
前端·css·tensorflow
里欧跑得慢10 小时前
CSS 模块化架构的演进:BEM、CSS Modules 到 CSS-in-JS 的反思
前端·css·flutter·web·css-in-js