JavaScript类数组对象
外观
JavaScript类数组对象[编辑 | 编辑源代码]
类数组对象(Array-like Object)是JavaScript中一类特殊对象,它们具有数字索引属性和length
属性,但不具备数组原型方法(如push()
、forEach()
等)。理解这类对象对于处理DOM操作、函数参数等场景至关重要。
核心特征[编辑 | 编辑源代码]
类数组对象需满足以下条件:
- 具有从0开始的连续数字键(
"0"
,"1"
, ...) - 包含
length
属性表示元素数量 - 不继承自
Array.prototype
典型示例[编辑 | 编辑源代码]
以下是一个手工创建的类数组对象:
const arrayLike = {
0: 'apple',
1: 'banana',
2: 'cherry',
length: 3
};
常见类数组对象[编辑 | 编辑源代码]
对象类型 | 说明 | 转换必要性 | arguments |
函数参数集合 | 常需转换 | NodeList | document.querySelectorAll() 返回结果 |
现代API可不转换 | HTMLCollection | document.getElementsByClassName() 等返回结果 |
通常需要转换 |
---|
检测方法[编辑 | 编辑源代码]
可通过以下特征判断:
function isArrayLike(obj) {
return obj != null
&& typeof obj === 'object'
&& typeof obj.length === 'number'
&& obj.length >= 0
&& obj.length % 1 === 0
&& obj.length <= Math.pow(2, 32) - 1;
}
转换方法[编辑 | 编辑源代码]
使用Array.from()[编辑 | 编辑源代码]
ES6推荐方式:
const realArray = Array.from(arrayLike);
// 输出: ['apple', 'banana', 'cherry']
扩展运算符[编辑 | 编辑源代码]
适用于可迭代对象:
const realArray = [...arrayLike];
// 注意:需对象实现@@iterator
传统slice方法[编辑 | 编辑源代码]
const realArray = Array.prototype.slice.call(arrayLike);
实际应用案例[编辑 | 编辑源代码]
处理函数参数[编辑 | 编辑源代码]
function sum() {
return Array.from(arguments).reduce((acc, val) => acc + val, 0);
}
console.log(sum(1, 2, 3)); // 输出: 6
DOM元素操作[编辑 | 编辑源代码]
const divs = document.querySelectorAll('div');
// NodeList转换为数组后使用map
Array.from(divs).map(div => div.textContent);
性能考虑[编辑 | 编辑源代码]
当处理大型类数组对象时:
Array.from()
比slice
更快- 现代浏览器已优化NodeList的遍历,某些情况可不转换
类数组与迭代器[编辑 | 编辑源代码]
数学表示[编辑 | 编辑源代码]
类数组对象可表示为:
进阶技巧[编辑 | 编辑源代码]
自定义类数组[编辑 | 编辑源代码]
通过定义length
和索引属性:
const customArrayLike = {
[Symbol.iterator]: function*() {
for(let i = 0; i < this.length; i++) {
yield this[i];
}
},
0: 'first',
1: 'second',
length: 2
};
性能测试比较[编辑 | 编辑源代码]
方法 | 时间(ms) | Array.from |
120 | slice.call |
180 | 扩展运算符 | 150 |
---|
页面模块:Message box/ambox.css没有内容。
某些"类数组"可能具有非连续索引(如 {0:'a', 2:'c', length:3} ),转换后会产生稀疏数组 |
总结[编辑 | 编辑源代码]
- 类数组对象广泛存在于DOM操作、函数参数等场景
- ES6的
Array.from
是最安全的转换方式 - 现代JavaScript引擎已优化常见类数组操作
- 实现
@@iterator
可使对象同时支持类数组和可迭代协议