JavaScript 类型检查操作符typeof 和 instanceof 的区别对比
作者:_璐-
本文给大家介绍JavaScript类型检查操作符typeof和instanceof的区别,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
typeof 和 instanceof 都是 JavaScript 中用于类型检查的操作符,但它们的工作方式和应用场景有显著不同。
1. 基本区别对比
| 特性 | typeof | instanceof |
|---|---|---|
| 操作目标 | 适用于所有 JavaScript 值 | 只适用于对象 |
| 返回值 | 返回类型名称的字符串 | 返回布尔值 |
| 检查内容 | 检查值的类型 | 检查对象的原型链 |
| 对原始值的处理 | 有效 | 总是返回 false |
| 对数组的检查 | 返回 "object" | arr instanceof Array → true |
| 对 null 的检查 | 返回 "object"(历史遗留问题) | null instanceof Object → false |
| 跨窗口/框架问题 | 无影响 | 可能有影响 |
2. 详细区别解释
2.1 工作原理不同
typeof:
- 返回一个表示操作数类型的字符串
- 对于原始值直接返回对应的类型名称
- 对于对象,通常返回 "object"(函数返回 "function")
typeof 42; // "number"
typeof "hello"; // "string"
typeof true; // "boolean"
typeof undefined; // "undefined"
typeof null; // "object" (历史遗留问题)
typeof {}; // "object"
typeof []; // "object"
typeof function(){}; // "function"instanceof:
- 检查构造函数的
prototype属性是否出现在对象的原型链中 - 只对对象有效,原始值总是返回 false
[] instanceof Array; // true [] instanceof Object; // true new Date() instanceof Date; // true 42 instanceof Number; // false "str" instanceof String; // false
2.2 对原始值的处理
typeof 可以正确处理原始值:
typeof 42; // "number" typeof "hello"; // "string" typeof true; // "boolean" typeof undefined; // "undefined" typeof null; // "object" (这是唯一例外)
instanceof 对原始值总是返回 false:
42 instanceof Number; // false "hello" instanceof String; // false true instanceof Boolean; // false
2.3 对数组的检查
typeof 无法区分数组和普通对象:
typeof []; // "object"
typeof {}; // "object"instanceof 可以检测数组:
[] instanceof Array; // true
{} instanceof Array; // false2.4 对 null 的检查
typeof 的著名陷阱:
typeof null; // "object" (这是历史遗留问题)
instanceof 正确处理 null:
null instanceof Object; // false
2.5 继承关系的检查
instanceof 可以检查继承关系:
class Animal {}
class Dog extends Animal {}
let dog = new Dog();
dog instanceof Dog; // true
dog instanceof Animal; // truetypeof 无法检查继承关系:
typeof dog; // "object" (无法知道是Dog还是Animal)
3. 使用场景对比
适合使用typeof的情况
检查变量是否已定义:
if (typeof variable === 'undefined') {
// 变量未定义
}检查基本类型:
function add(a, b) {
if (typeof a !== 'number' || typeof b !== 'number') {
throw new Error('参数必须是数字');
}
return a + b;
}区分函数和其他对象:
if (typeof callback === 'function') {
callback();
}适合使用instanceof的情况
检查对象的具体类型:
if (value instanceof Date) {
console.log(value.getFullYear());
}检查自定义类的实例:
class User {}
let user = new User();
if (user instanceof User) {
// 处理用户对象
}检查继承关系:
if (dog instanceof Animal) {
// 处理动物对象
}4. 特殊注意事项
4.1 跨窗口/框架问题
instanceof 在不同 iframe 或窗口之间可能不可靠:
// 假设array来自另一个iframe let iframeArray = window.frames[0].Array; let arr = new iframeArray(1, 2, 3); console.log(arr instanceof Array); // false
解决方法:
console.log(Array.isArray(arr)); // true
4.2 构造函数原型被修改
修改构造函数的原型会影响 instanceof 的结果:
function Foo() {}
let foo = new Foo();
console.log(foo instanceof Foo); // true
// 修改原型
Foo.prototype = {};
console.log(foo instanceof Foo); // false4.3 手动实现类型检查
对于更复杂的类型检查,可以结合使用:
function getType(obj) {
if (obj === null) return "null";
if (Array.isArray(obj)) return "array";
if (obj instanceof Date) return "date";
return typeof obj;
}
console.log(getType([])); // "array"
console.log(getType(null)); // "null"
console.log(getType(new Date())); // "date"
console.log(getType(42)); // "number"5. 总结对比表
| 场景 | typeof | instanceof | 推荐方案 |
|---|---|---|---|
| 检查基本类型 | ✔️ 优秀 | ❌ 无效 | typeof |
| 检查数组 | ❌ 不足 | ✔️ 可用 | Array.isArray() |
| 检查 null | ❌ 陷阱 | ✔️ 正确 | obj === null |
| 检查函数 | ✔️ 优秀 | ❌ 无效 | typeof |
| 检查自定义类实例 | ❌ 不足 | ✔️ 优秀 | instanceof |
| 检查继承关系 | ❌ 无效 | ✔️ 优秀 | instanceof |
| 检查跨窗口对象 | ✔️ 可用 | ❌ 不可靠 | 特定API(如Array.isArray()) |
6. 最佳实践建议
- 优先使用专用方法:
- 检查数组用
Array.isArray() - 检查 null 用
obj === null
- 检查数组用
- 组合使用:
function isNumber(value) {
return typeof value === 'number' || value instanceof Number;
}- 理解局限性:
typeof null返回 "object"instanceof对原始值无效- 跨窗口对象检查问题
- 考虑使用现代类型检查:
- TypeScript 提供编译时类型检查
- 使用
Object.prototype.toString.call()更精确 - 通过理解
typeof和instanceof的区别和适用场景,你可以更准确地编写类型检查逻辑,避免常见的 JavaScript 类型陷阱。
到此这篇关于JavaScript 类型检查操作符typeof 和 instanceof 的区别详解的文章就介绍到这了,更多相关js typeof 和 instanceof 区别内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
