typeof
和 instanceof
都是 JavaScript 中用于类型检查的操作符,但它们的用途、工作原理和适用场景有显著区别。
一、typeof
操作符
作用:
- 返回一个表示操作数基本类型的字符串。
- 主要用于检查原始类型(primitive types)。
返回值(字符串):
值 | typeof 结果 |
---|---|
undefined | "undefined" |
null | "object" ⚠️(历史遗留 bug) |
true / false | "boolean" |
123 / NaN / Infinity | "number" |
"hello" | "string" |
Symbol('id') | "symbol" |
BigInt(10) | "bigint" |
函数 | "function" |
其他对象(数组、日期、正则等) | "object" |
示例:
typeof "hello" // "string"
typeof 42 // "number"
typeof true // "boolean"
typeof undefined // "undefined"
typeof function(){} // "function"
typeof [] // "object"
typeof {} // "object"
typeof null // "object" ← 问题!
特点:
- 只能区分原始类型和函数。
- 对所有对象(包括数组、日期等)都返回
"object"
,无法进一步区分。 - 无法识别自定义构造函数的实例类型。
- 返回值是字符串。
二、instanceof
操作符
作用:
- 检查一个对象是否是某个构造函数的实例。
- 基于原型链(prototype chain)进行判断。
语法:
object instanceof Constructor
工作原理:
- 检查
Constructor.prototype
是否存在于object
的原型链上。
示例:
[] instanceof Array // true
[] instanceof Object // true(数组也是对象)
{} instanceof Object // true
new Date() instanceof Date // true
/abc/ instanceof RegExp // true
function(){} instanceof Function // true
// 自定义构造函数
function Person() {}
const p = new Person();
p instanceof Person // true
p instanceof Object // true
特点:
- 适用于对象类型,特别是区分内置对象(如
Array
、Date
)和自定义类。 - 可以利用原型链的继承关系(如
Array
也是Object
的实例)。 - 对原始类型使用
instanceof
总是返回false
:
"hello" instanceof String // false
42 instanceof Number // false
true instanceof Boolean // false
(因为原始值不是对象,没有原型链)
三、关键区别对比
特性 | typeof | instanceof |
---|---|---|
主要用途 | 检查基本类型(原始类型) | 检查对象是否为某构造函数的实例 |
适用类型 | 原始类型、函数、对象 | 主要用于对象 |
对 null 的处理 | typeof null === "object" (错误) | null instanceof Object → false (正确) |
对数组的处理 | typeof [] === "object" (无法区分) | [] instanceof Array → true (可区分) |
工作原理 | 基于值的内部类型标签 | 基于原型链(prototype ) |
返回值 | 字符串(如 "string" , "number" ) | 布尔值(true / false ) |
原始值检查 | ✅ 可以 | ❌ 不适用(总是 false ) |
自定义类检查 | ❌ 无法识别(返回 "object" ) | ✅ 可以 |
四、如何选择?
场景 | 推荐操作符 |
---|---|
检查变量是否为 undefined | typeof x === "undefined" (安全) |
检查是否为字符串、数字、布尔值等原始类型 | typeof |
检查是否为函数 | typeof fn === "function" |
检查是否为数组 | Array.isArray(arr) (✅ 最佳)或 arr instanceof Array |
检查是否为日期、正则等内置对象 | instanceof |
检查自定义类的实例 | instanceof |
💡 注意:检查数组时,推荐使用
Array.isArray()
,因为它更可靠(instanceof
在 iframe 等多全局环境中有问题)。
五、总结
问题 | 回答 |
---|---|
typeof 是什么? | 一个操作符,返回表示值的基本类型的字符串,适用于原始类型和函数。 |
instanceof 是什么? | 一个操作符,基于原型链检查对象是否是某个构造函数的实例,适用于对象类型。 |
核心区别 | typeof 关注“是什么类型”(原始类型),instanceof 关注“是谁的实例”(对象继承关系)。 |
一句话:用 typeof
判断原始类型,用 instanceof
判断对象的构造来源。
THE END