{{JS}}类似数组的对象

本文探讨了JavaScript数组的独特特性,包括length属性的特殊行为及其作为Array实例的应用。此外,还介绍了类似数组的对象,这类对象虽然不具备数组的所有特性,但在许多情况下可以像处理数组一样进行操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一个JS数组是特殊的, 因为
1.它的length属性有些特殊行为:
1).当新的元素添加到列表中,其值自动更新;
2).设置这一属性可以扩展或截断数组.
2.JS数组也是Array的实例,不同的Array方法可以通过它们来调用.

1, 2都是JS数组的独特特性,但它们不是定义一个数组的最基本的特性.把任何具有一个length属性及相应的非负整数属性的对象作为一种数组, 称之为”类似数组“.

这种类似数组的对象出现频率不高, 而且也不能在它们之上调用数组方法或者通过length属性期待特殊的行为1)2), 但仍然可以用遍历一个真正数组的代码来遍历它们. 事实上很多数组算法对于类似数组的对象和真正的数组对象都是适用的, 只要不尝试对数组添加元素或者改变length属性, 就可以把类似数组的对象当作真正的数组来对待.

如下创建一个类似数组,然后遍历该类似数组:
var a = {};

var i = 0;
// 不小心就引进了一个小bug
while( i++ < 10) {
a[i] = i*i;
}

while( i < 10) {
a[i] = i*i;
i++;
}
a.length = i;

var total = 0;
for(var j = 0, len = a.length; j < len; j++) {
total += a[j];
}

特别地,函数中的Arguments对象就是一个类似数组的对象; 而getElementsByTagName()返回的DOM结点列表也是类似数组的对象.
<think>我们正在讨论JavaScript中的类数组对象。根据引用,类数组对象是“看上去像数组,又不是数组”的对象,它们具有数字下标属性、length属性,但没有数组的方法(如push, pop等)。常见的例子包括函数的arguments对象和DOM操作返回的NodeList。 关键特征: 1. 有数字索引(下标)访问元素 2. 有length属性,表示元素个数 3. 没有数组的内置方法(如push, slice等) 使用方法: 1. 创建类数组对象:可以按照引用[2]和[3]的方法,创建一个空对象,然后添加数字下标属性,并设置length属性。 2. 将类数组对象转换为真正的数组:可以使用Array.prototype.slice.call()或Array.from()(ES6)方法,这样就能使用数组的方法了。 3. 借用数组方法:如引用[3]和[4]提到的,可以通过Function.call或Function.apply来借用数组的方法(例如Array.prototype.push.call)。 注意:引用[5]提到,转换后的数组会失去原有类数组对象的一些特性(比如用字符串作为属性名访问元素的能力)。 下面我们通过示例来详细说明。</think>### JavaScript 类数组对象详解 #### 1. **什么是类数组对象?** 类数组对象(Array-like Object)指**具有数字索引和 `length` 属性,但缺乏数组方法(如 `push`, `pop`)的对象**。其核心特征: - **数字下标访问**:可通过 `obj[0]`、`obj[1]` 访问元素 - **`length` 属性**:标识元素数量 - **非真正数组**:无法直接调用 `Array.prototype` 方法[^1][^4][^5] 常见类数组对象:函数的 `arguments`、DOM 的 `NodeList`、字符串等。 --- #### 2. **创建类数组对象** 通过手动添加属性和 `length` 实现: ```javascript // 步骤1:创建空对象 const arrayLike = {}; // 步骤2:添加数字下标属性 arrayLike[0] = "a"; arrayLike[1] = "b"; // 步骤3:设置length和splice(模拟数组行为) arrayLike.length = 2; arrayLike.splice = Array.prototype.splice; // 可选,使控制台输出类似数组 ``` 此时 `arrayLike` 可像数组一样迭代,但无法直接调用 `arrayLike.push()`[^1][^3]。 --- #### 3. **类数组对象的使用方法** ##### (1) **转换为真实数组** 使用 `Array.from()` 或 `Array.prototype.slice`: ```javascript // 方法1:ES6的Array.from const realArray1 = Array.from(arrayLike); // 方法2:借用数组的slice方法 const realArray2 = Array.prototype.slice.call(arrayLike); ``` 转换后可调用数组方法(如 `slice`, `push`)[^4][^5]。 ##### (2) **借用数组方法** 不转换直接调用数组方法: ```javascript // 类数组对象使用数组的push方法 Array.prototype.push.call(arrayLike, "c"); console.log(arrayLike.length); // 输出3 console.log(arrayLike[2]); // 输出"c" // 类数组对象使用数组的join方法 const str = Array.prototype.join.call(arrayLike, "-"); console.log(str); // 输出"a-b-c" ``` > ⚠️ 注意:部分方法(如 `concat`)可能不兼容类数组对象[^3][^4]。 --- #### 4. **典型应用场景** - **处理 `arguments` 对象**: ```javascript function sum() { const args = Array.prototype.slice.call(arguments); return args.reduce((a, b) => a + b); } console.log(sum(1, 2, 3)); // 输出6 ``` - **操作 DOM 集合**: ```javascript const divs = document.querySelectorAll("div"); // NodeList是类数组 const divArray = Array.from(divs); divArray.forEach(div => console.log(div)); ``` --- #### 5. **注意事项** - 类数组对象的 `length` 不会自动更新,需手动维护[^2]。 - 转换为真实数组后会丢失非数字键属性(如 `obj.name`)[^5]。 - 优先使用 `Array.from()`(ES6)代替 `slice.call()`,代码更简洁。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值