个人博客:haichenyi.com。感谢关注
1. 目录
- 1–目录
- 2–typeof 操作符
- 3–instanceof 操作符
- 4–Object.prototype.toString.call()
- 5–Array.isArray()
- 6–=== 严格相等
- 7–constructor 属性
- 8–Symbol.toStringTag(ES6+)
2. typeof 操作符
功能:检测基本数据类型。
返回结果:返回类型字符串(如 “number”, “string”)
特点:
无法区分 null(返回 “object”)和对象类型。
无法区分数组、对象、日期等引用类型(均返回 “object”)。
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" (历史遗留问题)
console.log(typeof []); // "object"
console.log(typeof {}); // "object"
3. instanceof 操作符
功能:检测对象是否为某个构造函数的实例
特点:
用于检测引用类型(如数组、自定义对象)。
无法检测基本数据类型。
跨窗口/框架时可能失效(不同全局环境下的构造函数不同)
console.log([] instanceof Array); // true
console.log({} instanceof Object); // true
console.log(new Date() instanceof Date); // true
function Person() {}
const person = new Person();
console.log(person instanceof Person); // true
4. Object.prototype.toString.call()
功能:最精确的类型检测方法,可区分所有内置对象。
返回结果:格式为 [object Xxx](如 [object Array])。
特点:
适用于检测所有数据类型(包括基本类型和引用类型)。
可识别 null 和 undefined。
console.log(Object.prototype.toString.call(42)); // "[object Number]"
console.log(Object.prototype.toString.call("hello")); // "[object String]"
console.log(Object.prototype.toString.call(null)); // "[object Null]"
console.log(Object.prototype.toString.call(undefined)); // "[object Undefined]"
console.log(Object.prototype.toString.call([])); // "[object Array]"
console.log(Object.prototype.toString.call({})); // "[object Object]"
console.log(Object.prototype.toString.call(new Date())); // "[object Date]"
5. Array.isArray()
功能:专门检测变量是否为数组
特点:
ES5 引入,比 instanceof 更可靠(避免跨窗口问题)。
替代旧方法 arr instanceof Array。
console.log(Array.isArray([])); // true
console.log(Array.isArray({})); // false
6. === 严格相等
功能:检测 null 或 undefined
特点:
null 和 undefined 无法用 typeof 准确检测。
直接使用严格相等判断。
const value = null;
console.log(value === null); // true
const value2 = undefined;
console.log(value2 === undefined); // true
7. constructor 属性
功能:通过对象的构造函数属性判断类型。
特点:
不推荐使用,因为 constructor 可被修改。
对基本数据类型无效(如 42.constructor 会报错)。
const arr = [];
console.log(arr.constructor === Array); // true
const obj = {};
console.log(obj.constructor === Object); // true
// 可能被篡改
arr.constructor = Object;
console.log(arr.constructor === Array); // false
8. Symbol.toStringTag
功能:允许对象自定义 Object.prototype.toString 返回的标签。
特点:
用于高级场景(如自定义类)。
不影响 typeof 或 instanceof。
class MyClass {
get [Symbol.toStringTag]() {
return "MyClass";
}
}
const obj = new MyClass();
console.log(Object.prototype.toString.call(obj)); // "[object MyClass]"
PS:整篇文章,精炼一下,如下
方法对比与选择指南
检测方式 | 适用场景 | 注意事项 |
---|---|---|
typeof | 检测基本数据类型(除null) | 无法区分null和对象 |
instanceof | 检测引用类型(如数组,自定义对象) | 无法检测基本数据类型,跨窗口失效 |
Object.prototype.toString.call() | 精确检测所有类型,推荐 | 需配合.call方法使用 |
Array.isArray() | 检测数组 | 只能用于检测数组,无法检测其他 |
=== 严格相等 | 检测null和undefined | 只能检测这两个类型,无法检测其他 |
constructor 属性 | 快速检测已知构造函数 | 构造函数可被篡改,不推荐 |
Symbol.toStringTag | 自定义对象的类型标签 | 高级用法,兼容性需注意 |
最佳实践
a. 基本类型:使用 typeof(注意 null 的陷阱)。
b. 引用类型:优先使用 Object.prototype.toString.call()。
c. 数组检测:使用 Array.isArray()。
d. null/undefined:直接使用 === 判断。
f. 自定义类型:结合 instanceof 和 Symbol.toStringTag