1. typeof 运算符
typeof是一个用来检测变量的基本数据类型的运算符。它可以返回以下几种类型的字符串:“undefined”、“boolean”、“number”、“string”、“object”、“function” 和 “symbol”(ES6+)。需要注意的是,对于 null 和 array,typeof 都返回 “object”,这可能导致一些混淆。
javascript">javascript
console.log(typeof 42); // "number"
console.log(typeof 'Hello'); // "string"
console.log(typeof true); // "boolean"
console.log(typeof {}); // "object"
console.log(typeof []); // "object"
console.log(typeof null); // "object"
console.log(typeof function() {}); // "function"
- 优点:
- 直接且易于理解,用于基础数据类型的检测非常有效。
- 缺点:
对于复杂类型(如数组、null、正则表达式),返回的结果不够准确。例如,数组和普通对象都返回 “object”,null 也返回 “object”,这可能会导致误解。
2. instanceof 运算符
instanceof 用于检测一个对象是否是另一个对象的实例。它可以用于检查对象的构造函数。
javascript">console.log([] instanceof Array); // true
console.log({} instanceof Object); // true
console.log(new Date() instanceof Date); // true
console.log(/regex/ instanceof RegExp); // true
console.log([] instanceof Object); // true (数组也是对象)
- 优点:
- 能够检查对象的构造函数,区分不同的对象类型(例如区分数组和普通对象)。
- 缺点:
对于跨窗口或跨框架的对象,instanceof 可能无法正确识别,因为它依赖于构造函数的 prototype。例如,在不同的浏览器窗口中创建的对象可能无法识别。
- 改进:
可以用 Object.prototype.toString.call() 来补充这种情况下的类型检测。
3. Array.isArray()
Array.isArray() 方法用于检测一个对象是否是数组。这是 typeof 和 instanceof 无法直接检测数组的情况。
javascript">console.log(Array.isArray([])); // true
console.log(Array.isArray({})); // false
console.log(Array.isArray('string')); // false
console.log(Array.isArray(new Array())); // true
- 优点:
- 专门用于检测数组,避免了 typeof 对数组的模糊处理。
- 缺点:
- 仅限于数组检测,对于其他数据类型不适用。
改进:
适用于需要明确检测数组的场景,如数组操作前的验证。
4. Object.prototype.toString.call()
Object.prototype.toString.call() 方法提供了最准确的方式来检测对象的原始类型,包括Array、Date、RegExp 等。
javascript">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]"
console.log(Object.prototype.toString.call(/regex/)); // "[object RegExp]"
console.log(Object.prototype.toString.call(null)); // "[object Null]"
console.log(Object.prototype.toString.call(undefined)); // "[object Undefined]"
- 优点:
- 提供最准确的类型检测,能够区分大多数数据类型,包括 null 和 undefined。
- 缺点:
- 语法相对复杂,需要调用 Object.prototype.toString.call()。
5. Number.isNaN() 和 isNaN()
Number.isNaN() 方法用于检测一个值是否是 NaN 且其类型为 Number。
isNaN()方法则会先尝试将值转换为数字,然后再判断是否为 NaN。
javascript">console.log(Number.isNaN(NaN)); // true
console.log(Number.isNaN('string')); // false
console.log(isNaN(NaN)); // true
console.log(isNaN('string')); // true (因为 'string' 被转换成 NaN)
console.log(isNaN(42)); // false
- 优点:
- Number.isNaN() 准确检测 NaN,避免了 isNaN() 的类型转换问题。
- 缺点:
- isNaN() 会将非数字值转换为 NaN,可能导致误判。
改进:
在需要检查 NaN 时使用 Number.isNaN(),避免 isNaN() 的类型转换问题。
6. constructor 属性
constructor 属性可以用来检测一个对象的构造函数,但这种方法不如 instanceof 可靠,因为它可能会被改变。
javascript">console.log(([]).constructor === Array); // true
console.log(({}).constructor === Object); // true
console.log((new Date()).constructor === Date); // true
console.log((/regex/).constructor === RegExp); // true
console.log((42).constructor === Number); // true
- 优点:
- 直接检测构造函数,语法简单明了。
- 缺点:
- constructor 属性可能被篡改,因此不总是可靠。例如,如果对象的 constructor 被修改,检测结果可能不准确。
7 总结
- typeof 适用于基本数据类型的检查,但对于 null 和数组不够精确。
- instanceof 适用于检查对象是否为特定构造函数的实例。
- Array.isArray() 专门用于检测数组。
- Object.prototype.toString.call() 提供了最准确的类型检测方式。
- Number.isNaN() 用于检测 NaN,避免 isNaN() 的一些陷阱。