在 JavaScript 中,类数组对象(Array-like Object) 是一种模拟数组结构的对象,它具有 length 属性和一系列以数字为键的属性值,但不具备数组的原型方法(如 push、slice 等),因此不能直接调用数组的方法。
✅ 一句话总结
类数组对象是一种具有
length属性和索引属性的对象,常见于arguments、DOM 操作返回值等场景,虽然结构类似数组,但不能直接使用数组方法,需要转换后才能操作。
✅ 一、类数组对象的定义
一个对象如果满足以下两个条件,就可以被称为类数组对象:
- 拥有
length属性,值为一个非负整数; - 具有索引属性,即键为
0、1、2等数字;
示例:
const arrayLike = {
0: 'a',
1: 'b',
2: 'c',
length: 3
};
📌 虽然结构类似数组,但不能直接调用数组方法:
arrayLike.push('d'); // ❌ 报错:arrayLike.push is not a function
✅ 二、常见的类数组对象
🔹 1. arguments 对象
function example() {
console.log(arguments); // { 0: 'a', 1: 'b', length: 2 }
}
example('a', 'b');
- 包含函数调用时传入的所有参数;
- 是典型的类数组对象;
🔹 2. DOM 操作返回值
const elements = document.querySelectorAll('div');
console.log(elements); // NodeList { 0: div, 1: div, length: 2 }
NodeList、HTMLCollection等都是类数组对象;
🔹 3. 函数本身(Function)
function example(a, b) {}
console.log(example.length); // 2
- 函数对象有一个
length属性,表示形参个数; - 虽不常用于数据操作,但也符合类数组结构;
✅ 三、类数组对象如何转换为数组?
虽然类数组对象不能直接使用数组的方法,但可以通过以下几种方式将其转换为真正的数组,以便使用数组的方法进行操作。
🔹 方法 1:Array.prototype.slice.call(arrayLike)
const arr = Array.prototype.slice.call(arrayLike);
- ✅ 原理:借用数组的
slice方法,对类数组进行“切片”; - ✅ 兼容性好,适用于大多数浏览器;
🔹 方法 2:Array.prototype.splice.call(arrayLike, 0)
const arr = Array.prototype.splice.call(arrayLike, 0);
- ✅ 原理:使用
splice方法从索引 0 开始删除所有元素并返回; - ⚠️ 会修改原始对象(清空类数组对象);
🔹 方法 3:Array.prototype.concat.apply([], arrayLike)
const arr = Array.prototype.concat.apply([], arrayLike);
- ✅ 原理:通过
concat合并空数组和类数组; - ✅ 简洁有效,兼容性好;
🔹 方法 4:Array.from(arrayLike)
const arr = Array.from(arrayLike);
- ✅ ES6 新增方法,专为类数组和可迭代对象设计;
- ✅ 代码简洁,推荐使用;
- ✅ 支持映射函数:
const arr = Array.from(arrayLike, item => item.toUpperCase());
🔹 方法 5:扩展运算符(Spread Operator)
const arr = [...arrayLike];
- ✅ ES6 新增,简洁直观;
- ✅ 适用于可迭代对象(如
arguments、NodeList); - ⚠️ 若对象不可迭代,会报错;
✅ 四、类数组对象与数组的对比
| 特性 | 类数组对象 | 数组 |
|---|---|---|
是否有 length 属性 | ✅ 有 | ✅ 有 |
| 是否有索引属性 | ✅ 有 | ✅ 有 |
| 是否能使用数组方法 | ❌ 不能 | ✅ 可以 |
是否继承自 Array.prototype | ❌ 否 | ✅ 是 |
| 是否可迭代 | ❌ 通常不可迭代(视具体对象而定) | ✅ 是 |
| 如何转换为数组 | 使用 slice、from、扩展运算符等 | 无需转换 |
✅ 五、一句话总结
类数组对象是一种结构类似数组但不具备数组方法的对象,常见于
arguments和 DOM 操作中。使用Array.prototype.slice、Array.from、扩展运算符等方式可以将其转换为真正的数组,以便使用数组方法进行操作。
💡 进阶建议
- 使用
Array.from或扩展运算符处理现代项目; - 在兼容性要求较高的项目中使用
slice; - 对
NodeList使用Array.from可以调用map、filter等方法; - 注意
splice会修改原对象,使用时需谨慎;