如何区分typeof为object的数组与普通对象,正确统计真实对象数量
如何正确统计数组中“真实”对象的数量
问题场景
需要编写函数接收包含多种数据类型的数组,返回其中“真实”对象(排除数组、null等)的数量。当前代码将数组[]也统计为对象,导致结果错误,且尝试type !== []的判断无效。
原代码:
function countTheObjects(arr) { let howManyObj = 0; arr.forEach(function (type) { console.log(typeof type); if (typeof type === "object" && type !== null) { howManyObj++; } }); return howManyObj; } console.log( countTheObjects([1, {}, [], null, null, "foo", 3, 4, 5, {}, {}, {}, "foo"]) );
原代码运行结果为5,但正确结果应为4,因为数组[]被错误统计。
问题原因
typeof []返回"object",所以原判断会把数组算入对象范畴。type !== []无效的核心原因:每一个数组都是独立的引用类型,[] === []的结果是false,这个判断永远为真,无法起到排除数组的作用。
解决方案
可以通过两种方式准确区分“真实”对象与数组、null:
方法1:使用Array.isArray()排除数组
Array.isArray()是ES5引入的方法,专门用来判断值是否为数组,兼容性良好。修改后的代码如下:
function countTheObjects(arr) { let howManyObj = 0; arr.forEach(function(item) { // 排除null和数组,仅统计纯对象 if (typeof item === "object" && item !== null && !Array.isArray(item)) { howManyObj++; } }); return howManyObj; }
方法2:使用Object.prototype.toString.call()精确判断类型
Object.prototype.toString.call()可以返回更精确的类型标识,不同类型的返回值如下:
- 纯对象:
[object Object] - 数组:
[object Array] - null:
[object Null]
利用这一点可以直接判断是否为纯对象,代码更简洁:
function countTheObjects(arr) { let howManyObj = 0; arr.forEach(function(item) { if (Object.prototype.toString.call(item) === '[object Object]') { howManyObj++; } }); return howManyObj; }
验证结果
调用测试数组[1, {}, [], null, null, "foo", 3, 4, 5, {}, {}, {}, "foo"],两种方法均返回4,符合预期。
内容的提问来源于stack exchange,提问作者Vincenzo Chiovaro
相关产品推荐
相关产品推荐

