在 JavaScript 中,正确地识别数据类型对于程序的健壮性和性能至关重要。我会通过一些代码示例,从基础的 typeof 检测开始,逐步揭示不同类型判断方法。
1. typeof 操作符
console.log(typeof 42); // "number"
console.log(typeof "Hello"); // "string"
console.log(typeof true); // "boolean"
console.log(typeof undefined); // "undefined"
console.log(typeof Symbol()); // "symbol"
console.log(typeof {}); // "object"
console.log(typeof null); // "object",这是 `typeof` 的一个陷阱
typeof 是最简单的类型检测方式,用于识别原始类型。但是,它不能区分不同的引用类型,对于所有引用类型,包括 null,都会返回 "object"。这是因为所有引用类型在底层都表现为对象,其二进制表示的前三位均为 0。因此,typeof 并不足以区分不同的引用类型。
2. instanceof 操作符
function Person() {}
const person = new Person();
console.log(person instanceof Person); // true
console.log(person instanceof Object); // true
instanceof 用于检查一个对象是否是另一个构造函数的实例。它通过检查原型链来实现这一点。instanceof 并非万能。它依赖于原型链的完整性,如果原型链被破坏(例如,手动修改原型),instanceof 的判断可能会失效。此外,instanceof 不能跨域工作,即无法判断来自其他窗口或框架的对象类型。
3. Object.prototype.toString.call()
为了克服 typeof 和 instanceof 的限制,Object.prototype.toString.call() 提供了一种更精细的类型检测方法,可以区分不同引用类型,甚至 null 和 undefined。
function checkType(value) {
return Object.prototype.toString.call(value);
}
console.log(checkType(42)); // "[object Number]"
console.log(checkType("Hello")); // "[object String]"
console.log(checkType(true)); // "[object Boolean]"
console.log(checkType(undefined)); // "[object Undefined]"
console.log(checkType(null)); // "[object Null]"
console.log(checkType([])); // "[object Array]"
console.log(checkType({})); // "[object Object]"
4. Array.isArray()
在 ES5 中引入的 Array.isArray() 专门用于判断一个值是否为数组,它比 instanceof Array 更加安全,因为不受原型链污染的影响。
console.log(Array.isArray([])); // true
console.log(Array.isArray({})); // false
console.log(Array.isArray(document.body.children)); // false,虽然这是一个类数组对象
5. 自定义类型检查函数
我们还可以定义自己的类型检查函数,例如 isObject 和 myInstanceof 来满足特定需求。
function isObject(obj) {
return obj !== null && typeof obj === 'object';
}
function myInstanceof(L, R) {
let proto = L.__proto__ || L.constructor.prototype;
while (proto) {
if (proto === R.prototype) {
return true;
}
proto = proto.__proto__;
}
return false;
}
const arr = [];
console.log(isObject(arr)); // true
console.log(myInstanceof(arr, Array)); // true
通过以上代码示例,我们可以清晰地看到 JavaScript 中不同类型检测方法的特点和适用场景。从简单的 typeof 到更为复杂的 Object.prototype.toString.call(),再到专门化的 Array.isArray(),每种方法都有其独特的作用,了解并掌握它们,将有助于编写更高质量的代码。