Check if a value is an object in JavaScript

Check if a value is an object in JavaScript

技术背景

在 JavaScript 中,准确判断一个值是否为对象并非易事。因为 JavaScript 的数据类型系统较为复杂,typeof 操作符在判断对象时存在一些问题,例如它会将 null 也判定为 object,同时对于函数和数组的判定也不符合某些场景的需求。因此,我们需要掌握多种方法来准确判断一个值是否为对象。

实现步骤

1. 定义“对象”和“原始值”

在 JavaScript 中,每个值要么是对象,要么是原始值。原始值包括:stringnumberbigintbooleanundefinedsymbolnull。而对象则是除了这些原始值之外的其他值,例如 Object.prototype、数组、函数等。

2. 各种判断方法

使用 typeofArray.isArray

1
2
3
function isObject(o) {
return o !== null && typeof o === 'object' && Array.isArray(o) === false;
}

使用 instanceofconstructor

1
2
3
function isObject(o) {
return o instanceof Object && o.constructor === Object;
}

使用 Object.prototype.toString.call

1
2
3
function isObject(obj) {
return Object.prototype.toString.call(obj) === '[object Object]';
}

使用 Object 构造函数

1
2
3
function isObject(value) {
return Object(value) === value;
}

使用 constructor.name

1
2
3
function isObject(obj) {
return obj != null && obj.constructor.name === "Object";
}

使用可选链操作符

1
const isObj = o => o?.constructor === Object;

3. 不同方法的适用场景

  • 排除 null、数组和函数:可以使用 typeof x === 'object' && !Array.isArray(x) && x !== null
  • 判断普通对象:可以使用 Object.prototype.toString.call(obj) === '[object Object]' 或者 obj.constructor.toString().indexOf("Object") > -1
  • 判断是否为任何非原始值对象:可以使用 value != null && (typeof value === 'object' || typeof value === 'function')

核心代码

综合判断函数

1
2
3
4
5
6
7
8
9
10
11
12
function isObject(o) {
return null != o &&
typeof o === 'object' &&
Object.prototype.toString.call(o) === '[object Object]';
}

function isDerivedObject(o) {
return !isObject(o) &&
null != o &&
(typeof o === 'object' || typeof o === 'function') &&
/^\[object /.test(Object.prototype.toString.call(o));
}

测试代码

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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// TESTS

// is null an object?
console.log(
'is null an object?', isObject(null)
);

console.log(
'is null a derived object?', isDerivedObject(null)
);

// is 1234 an object?
console.log(
'is 1234 an object?', isObject(1234)
);

console.log(
'is 1234 a derived object?', isDerivedObject(1234)
);

// is new Number(1234) an object?
console.log(
'is new Number(1234) an object?', isObject(new Number(1234))
);

console.log(
'is new Number(1234) a derived object?', isDerivedObject(1234)
);

// is function object an object?
console.log(
'is (new (function (){})) an object?',
isObject((new (function (){})))
);

console.log(
'is (new (function (){})) a derived object?',
isObject((new (function (){})))
);

// is {} an object?
console.log(
'is {} an object?', isObject({})
);

console.log(
'is {} a derived object?', isDerivedObject({})
);

// is Array an object?
console.log(
'is Array an object?',
isObject([])
);

console.log(
'is Array a derived object?',
isDerivedObject([])
);

// is Date an object?
console.log(
'is Date an object?', isObject(new Date())
);

console.log(
'is Date a derived object?', isDerivedObject(new Date())
);

// is function an object?
console.log(
'is function an object?', isObject(function(){})
);

console.log(
'is function a derived object?', isDerivedObject(function(){})
);

最佳实践

  • 在实际开发中,根据具体需求选择合适的判断方法。如果需要排除数组和 null,可以使用 typeof x === 'object' && !Array.isArray(x) && x !== null
  • 对于需要判断普通对象的场景,Object.prototype.toString.call(obj) === '[object Object]' 是一个比较可靠的方法。
  • 如果使用框架,可以优先使用框架提供的判断函数,例如 jQuery 的 jQuery.type(obj)、Angular 的 angular.isObject(obj)、Underscore 和 Lodash 的 _.isObject(obj)

常见问题

typeof 操作符的局限性

typeof 操作符会将 null 判定为 object,同时对于函数和数组的判定也不符合某些场景的需求。例如:

1
2
3
typeof null; // "object"
typeof []; // "object"
typeof function() {}; // "function"

instanceof 的局限性

instanceof 无法正确判断 Object.prototypeObject.create(null) 是否为对象。例如:

1
2
3
4
5
function isObject(val) {
return val instanceof Object;
}
isObject(Object.prototype); // false
isObject(Object.create(null)); // false

Object.prototype.toString.call 的局限性

Object.prototype.toString.call 会对所有原始值返回 [object 类型名],可能会导致误判。例如:

1
2
Object.prototype.toString.call(3); // "[object Number]"
Object.prototype.toString.call(new Number(3)); // "[object Number]"

Check if a value is an object in JavaScript
https://119291.xyz/posts/2025-05-16.check-if-a-value-is-an-object-in-javascript/
作者
ww
发布于
2025年5月16日
许可协议