类数组
在 JavaScript 中,类数组(Array-like) 或类数组对象(Array-like Object) 是指那些==外观和行为类似数组==,但本质上不是 Array 实例的对象。
它们的核心特征是:
- 具有 ==
length属性==(表示元素数量); - 可以通过==索引(如
0、1、2)访问元素==; - 但==不具备
Array原型==方法(如push、map、forEach等)。
常见的类数组对象
arguments对象
函数内部的局部变量,包含函数调用时传递的所有参数。javascriptfunction sum() { console.log(arguments); // [1, 2, 3](类数组形式) console.log(arguments.length); // 3 console.log(arguments[0]); // 1(通过索引访问) } sum(1, 2, 3);DOM 集合
如document.getElementsByTagName()、document.querySelectorAll()返回的集合(HTMLCollection或NodeList)。javascriptconst divs = document.getElementsByTagName('div'); console.log(divs.length); // 页面中 div 的数量 console.log(divs[0]); // 第一个 div 元素字符串(
String)
字符串可以通过索引访问字符,且有length属性,也被视为类数组。javascriptconst str = "hello"; console.log(str.length); // 5 console.log(str[0]); // "h"自定义类数组对象
手动定义的具有length和索引属性的对象。javascriptconst arrLike = { 0: "a", 1: "b", 2: "c", length: 3 };
类数组与数组的区别
| 特性 | 类数组对象 | 数组(Array) |
|---|---|---|
| 原型链 | 原型通常是 Object.prototype | 原型是 Array.prototype |
| 数组方法 | 不具备(如 map、forEach 等) | 具备所有数组方法 |
instanceof Array | 返回 false | 返回 true |
类数组转换为真正的数组 由于类数组不支持数组方法,实际开发中常需要将其转换为真正的数组,以便使用 map、filter 等方法。常用转换方式:
Array.from()(推荐,ES6+)
专门用于将类数组或可迭代对象转换为数组。javascriptconst arrLike = { 0: 1, 1: 2, 2: 3, length: 3 }; const arr = Array.from(arrLike); console.log(arr); // [1, 2, 3] console.log(arr.map(x => x * 2)); // [2, 4, 6](可使用数组方法)扩展运算符(
...)(ES6+,==仅适用于可迭代对象==)
如NodeList、字符串等可迭代的类数组。javascriptconst divs = document.querySelectorAll('div'); const divArray = [...divs]; // 转换为数组 const str = "hello"; const strArray = [...str]; // ["h", "e", "l", "l", "o"]Array.prototype.slice.call()(传统方法)
利用slice方法的特性转换(slice不传参数时返回原数组的副本)。javascriptconst argumentsArr = Array.prototype.slice.call(arguments); // 等价于:[].slice.call(arguments)
总结
- 类数组对象是“长得像数组”的对象,核心特征是
length属性和索引访问; - 常见于
arguments、DOM 集合、字符串等; - 转换为真正的数组后,才能使用
Array的所有方法,常用Array.from()或扩展运算符实现转换。
理解类数组的特性有助于在处理 DOM 操作、函数参数等场景时避免错误(如直接调用数组方法导致的报错)。
有索引和 length 属性 => 类数组对象
javascript
let arrayLike = { // 有索引和 length 属性 => 类数组对象
0: "Hello",
1: "World",
length: 2
};
// Error (no Symbol.iterator)
for (let item of arrayLike) {}有一个全局方法 Array.from 可以接受一个可迭代或类数组的值,并从中获取一个“真正的”数组。然后我们就可以对其调用数组方法了。