类数组
约 350 字大约 1 分钟
2026-02-26
类数组(Array-like)是“看起来像数组”的对象:
- 有
length - 有按索引命名的属性(
0、1、2...) - 但原型链通常不是
Array.prototype
常见的类数组
function demo() {
console.log(arguments) // arguments 是典型类数组
console.log(Array.isArray(arguments)) // false
}
demo(1, 2, 3)
const nodeList = document.querySelectorAll('div')
console.log(Array.isArray(nodeList)) // false类数组与数组的区别
| 对比项 | 数组 | 类数组 |
|---|---|---|
| 原型 | Array.prototype | 通常是 Object.prototype |
是否可直接用 map/filter | 可以 | 不一定(多数不行) |
length | 有 | 通常也有 |
| 典型代表 | [] | arguments、NodeList |
转换为真正数组
Array.from
function sum() {
const args = Array.from(arguments)
return args.reduce((total, cur) => total + cur, 0)
}
console.log(sum(1, 2, 3)) // 6展开运算符
const list = document.querySelectorAll('div')
const arr = [...list]
console.log(Array.isArray(arr)) // trueslice.call
function toArray() {
return Array.prototype.slice.call(arguments)
}
console.log(toArray('a', 'b', 'c')) // ['a', 'b', 'c']手动构造一个类数组对象
如果一个对象满足索引结构 + length,并借用数组方法,也可以表现出“类数组行为”。
const arrayLike = {
0: 'js',
1: 'ts',
length: 2,
splice: Array.prototype.splice,
push: Array.prototype.push
}
arrayLike.push('vue')
console.log(arrayLike)
// {
// 0: 'js',
// 1: 'ts',
// 2: 'vue',
// length: 3,
// splice: f,
// push: f
// }典型题
const obj = {
2: 3,
3: 4,
length: 2,
splice: Array.prototype.splice,
push: Array.prototype.push
}
obj.push(1)
obj.push(2)
console.log(obj)
// {
// 2: 1,
// 3: 2,
// length: 4,
// splice: f,
// push: f
// }这里的关键点是:push 总是从 length 对应位置开始写入,再自增 length。
