在 JavaScript 开发中,我们经常会遇到一种特殊的数据结构------类数组对象(Array-like Object)。它看似像数组,但又不能直接使用数组的方法。理解类数组对象及其转换方式,是掌握 JavaScript 数据处理的关键一步。
✅ 一句话总结
类数组对象是具有
length
属性和数字索引的对象,常见于arguments
、DOM 查询结果等场景。虽然结构类似数组,但不能直接调用数组方法。可通过slice.call
、Array.from
、扩展运算符等方式转换为真正的数组。
✅ 一、什么是类数组对象?
🔹 定义
一个对象如果满足以下两个条件,就可以被称为类数组对象:
- 拥有
length
属性,值为非负整数; - 具有从
0
开始的数字索引属性;
🔹 示例
javascript
const arrayLike = {
0: 'apple',
1: 'banana',
2: 'orange',
length: 3
};
🔹 常见的类数组对象
类型 | 示例 |
---|---|
arguments 对象 |
函数内部访问参数 |
DOM 查询结果 | document.querySelectorAll() 返回 NodeList |
HTMLCollection |
getElementsByClassName() 返回结果 |
函数对象 | function.length 表示参数个数 |
✅ 二、为什么类数组不能直接使用数组方法?
- 类数组对象没有继承
Array.prototype
; - 因此不具备
push
、map
、forEach
等原型方法; - 尝试调用会报错:
javascript
arrayLike.push('grape'); // ❌ TypeError: arrayLike.push is not a function
✅ 三、类数组转换为数组的 5 种方法
🔹 方法 1:Array.prototype.slice.call(arrayLike)
javascript
const arr = Array.prototype.slice.call(arrayLike);
- ✅ 原理:借用数组的
slice
方法进行"切片"; - ✅ 兼容性好,适用于老版本浏览器;
- ✅ 推荐用于需要兼容性的项目;
🔹 方法 2:Array.prototype.splice.call(arrayLike, 0)
javascript
const arr = Array.prototype.splice.call(arrayLike, 0);
- ✅ 原理:使用
splice
从索引 0 开始删除所有元素并返回; - ⚠️ 副作用:会清空原始类数组对象;
- ❌ 不推荐用于需要保留原对象的场景;
🔹 方法 3:Array.prototype.concat.apply([], arrayLike)
javascript
const arr = Array.prototype.concat.apply([], arrayLike);
- ✅ 原理:将空数组与类数组合并;
- ✅ 代码简洁,兼容性好;
- ✅ 适用于大多数场景;
🔹 方法 4:Array.from(arrayLike)
javascript
const arr = Array.from(arrayLike);
- ✅ ES6 新增方法,专为类数组和可迭代对象设计;
- ✅ 语法简洁,语义清晰;
- ✅ 支持映射函数:
javascript
const upperArr = Array.from(arrayLike, item => item.toUpperCase());
- ✅ 现代项目推荐使用;
🔹 方法 5:扩展运算符(Spread Operator)
javascript
const arr = [...arrayLike];
- ✅ ES6 新增,代码最简洁;
- ✅ 可与其他数组操作链式调用;
- ✅ 适用于可迭代的类数组对象(如
NodeList
、arguments
); - ⚠️ 若对象不可迭代,会报错;
✅ 四、实战示例
场景 1:转换 arguments
javascript
function example() {
// 转换为数组后使用 map
const args = Array.from(arguments);
return args.map(arg => arg * 2);
}
console.log(example(1, 2, 3)); // [2, 4, 6]
场景 2:转换 DOM 查询结果
javascript
const nodeList = document.querySelectorAll('div');
const divArray = [...nodeList]; // 转为数组
divArray.forEach(div => div.classList.add('highlight'));
✅ 五、一句话总结
类数组对象是 JavaScript 中常见的数据结构,虽然不能直接使用数组方法,但通过
slice.call
、Array.from
或扩展运算符可以轻松转换为真正的数组,从而利用丰富的数组 API 进行数据处理。
💡 进阶建议
- 优先使用
Array.from
或扩展运算符(现代项目); - 兼容性要求高时使用
slice.call
; - 避免使用
splice.call
(会修改原对象); - 注意
arguments
在箭头函数中不可用; - 使用
Array.isArray()
可判断是否为真数组;