前言
前面我们认识了 JavaScript 中的各种数据类型,今天就来聊聊如何判断这些类型吧!🧐
1. 🔍 typeof 操作符
1.1 简单类型判断小能手
typeof 是 JavaScript 原生的操作符,用来快速判断原始数据类型(除 null 外)。它直接读取 JS 引擎内部的类型标记。
console.log(typeof(100)); // "number"
console.log(typeof('100')); // "string"
console.log(typeof(true)); // "boolean"
console.log(typeof(undefined)); // "undefined"
console.log(typeof(null)); // "object" 😅 (特殊!)
console.log(typeof({})); // "object"
console.log(typeof(Symbol())); // "symbol"
console.log(typeof(BigInt(100)));// "bigint"
1.2 为什么 typeof null === 'object'?
这是 JavaScript 早期设计的一个小“意外” 🐞:null 的内部表示是全零值,碰巧和对象的类型标记相同,所以 typeof 就把它误判为 object 啦!
2. 🔗 instanceof 操作符
2.1 检查“家族关系”
instanceof 用来检查一个对象是否属于某个构造函数或类(通过原型链查找)。
let date = new Date();
console.log(date instanceof Date); // true ✅
let set = new Set();
console.log(set instanceof Set); // true ✅
2.2 手动实现原理
它的核心是沿着原型链向上查找:
function myInstanceof(L, R) {
L = L.__proto__;
while (L) {
if (L === R.prototype) return true;
L = L.__proto__;
}
return false;
}
2.3 使用注意 ⚠️
- 原始值(如
10,"hello")直接判断会返回false(除非用new创建包装对象)。 null和undefined无法使用(会报错)。- 没有原型的对象(如
Object.create(null))也无法判断。
3. 🎭 Object.prototype.toString.call()
3.1 类型检测“终极武器” 💪
这个方法能精准返回任何值的内部类型标签(格式为 [object Type]):
console.log(Object.prototype.toString.call(10)); // [object Number]
console.log(Object.prototype.toString.call("hi")); // [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(Symbol())); // [object Symbol]
console.log(Object.prototype.toString.call([])); // [object Array]
console.log(Object.prototype.toString.call(new Set())); // [object Set]
console.log(Object.prototype.toString.call(function(){}));// [object Function]
3.2 为什么必须用 .call()?🤔
因为很多对象(如数组、函数)自己改写了 toString 方法:
let arr = [1, 2, 3];
console.log(arr.toString()); // "1,2,3" (数组自己的方法,不是类型信息!)
Object.prototype.toString.call(arr) 确保了:
- 调用最原始的
toString方法。 - 把
this正确指向我们要检测的值 (arr),从而获取其真实的内部类型标签。
4. ✅ Array.isArray() - 数组专属检测
专为数组设计的检测方法,简单又准确!优先推荐用它来判断数组:
console.log(Array.isArray([])); // true ✅
console.log(Array.isArray([1, 2, 3])); // true ✅
console.log(Array.isArray(new Array(5))); // true ✅
// 完美避开“像数组但不是数组”的对象
console.log(Array.isArray({ length: 3 })); // false ❌
console.log(Array.isArray("hello")); // false ❌
function test() {
console.log(Array.isArray(arguments)); // false ❌ (arguments是类数组)
}
test();
✨ 总结一下
typeof: 快速判断原始类型 (小心null返回"object")。instanceof: 检查对象与构造函数的关系 (原型链查找)。Object.prototype.toString.call(): 最通用的类型检测方法 (返回[object Type])。Array.isArray(): 判断数组的首选方法 👍。