002-JavaScript 类型判断方法详解

JavaScript 类型判断方法详解

1. 判断数据类型的常用方法

方法 说明 示例
typeof 返回基本类型字符串,对引用类型(除函数)返回 "object" typeof "str""string"
instanceof 检测构造函数的原型是否在对象原型链上(用于引用类型) [] instanceof Arraytrue
Object.prototype.toString.call() 最准确的类型判断方法,返回 [object Type] 格式字符串 toString.call(null)[object Null]
Array.isArray() ES5 新增的数组检测方法 Array.isArray([])true
=== 特殊值直接比较(null/undefined value === null

2. instanceof 原理

实现机制
沿着对象的原型链向上查找,检查构造函数的 prototype 属性是否出现在原型链中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
function myInstanceof(obj, constructor) {
// 获取对象的原型
let proto = Object.getPrototypeOf(obj);

while (proto) {
// 找到原型匹配
if (proto === constructor.prototype) return true;
// 继续向上查找
proto = Object.getPrototypeOf(proto);
}
return false;
}

// 测试
console.log(myInstanceof([], Array)); // true
console.log(myInstanceof({}, Object)); // true
console.log(myInstanceof([], Object)); // true(Array继承自Object)


**注意事项**:

* 对基本类型无效:`1 instanceof Number``false`
* 跨框架对象检测可能失效(不同执行环境有不同原型)
* 修改 `prototype` 可能导致意外行为

### 3. 判断空对象的 4 种方法

```javascript
const obj = {};

// 方法1:Object.keys(推荐)
Object.keys(obj).length === 0; // true

// 方法2:JSON.stringify
JSON.stringify(obj) === '{}'; // true

// 方法3:for...in 遍历
function isEmpty(obj) {
for (let key in obj) {
if (obj.hasOwnProperty(key)) return false;
}
return true;
}

// 方法4:Object.getOwnPropertyNames
Object.getOwnPropertyNames(obj).length === 0; // true

特殊案例处理

1
2
3
4
5
6
7
8
9
// Symbol 属性需单独检测
const symObj = { [Symbol('key')]: 'value' };
Object.getOwnPropertySymbols(symObj).length === 0; // false

// 不可枚举属性
const nonEnum = Object.create({}, {
hidden: { value: 'secret', enumerable: false }
});
Object.keys(nonEnum).length === 0; // true(需注意)

4. typeof null 的特殊性

1
typeof null; // "object"(历史遗留问题)

原因
JavaScript 早期设计时用二进制前三位标识类型:

  • 000:对象类型
  • 1:整型
  • 010:双精度浮点型
  • 100:字符串
  • 110:布尔型
    null 的二进制全为 0,被错误识别为对象类型

正确检测 null

1
const isNull = (value) => value === null;  // 直接全等比较

5. typeof NaN 的特殊性

1
typeof NaN; // "number"(符合IEEE 754标准)

NaN 的特性

  • 全称:Not-A-Number(非数字)
  • 是特殊的 Number 类型值
  • 由无效数学运算产生:0/0, Math.sqrt(-1)
  • 不等于任何值(包括自身):NaN === NaNfalse

检测 NaN 的方法

1
2
3
4
5
6
7
8
9
10
11
// ES6 推荐方法
Number.isNaN(NaN); // true

// 兼容旧环境方法
function isNaN(value) {
return value !== value; // NaN是唯一不自等的值
}

// 注意全局isNaN的缺陷(会先尝试类型转换)
isNaN("hello"); // true(字符串被转成NaN)
Number.isNaN("hello"); // false(严格检测)

类型判断总结表

表达式 结果 说明
typeof "hello" "string" 基本类型准确检测
typeof null "object" 历史遗留问题
typeof NaN "number" IEEE 754 标准定义
typeof function() {} "function" 函数的特殊处理
[] instanceof Array true 原型链检测
Object.prototype.toString.call({}) "[object Object]" 最可靠的类型判断