JavaScript类数组(伪数组)

108 阅读3分钟

类数组(伪数组)是一种特殊的数据结构,它看起来和数组相似,但却不完全具备数组的所有特性和方法。今天,就让我们深入探究一下 JavaScript 类数组,揭开它神秘的面纱。

一、什么是类数组

类数组对象通常具有一个 length 属性,并且属性名是索引(从 0 开始的整数),但它们并非真正的数组实例,不直接继承自 Array.prototype。常见的类数组对象有函数中的 arguments 对象、DOM 元素集合(如 document.getElementsByTagName 返回的结果)等。例如,当我们在一个函数中访问 arguments 时,它看起来像一个数组,可以通过索引访问其中的元素,也有 length 属性,但它并不是一个真正的数组,不能直接调用数组的方法,如 pushpop 等。

二、类数组与数组的区别

  1. 原型链差异 数组是基于 Array 构造函数创建的,继承了丰富的数组方法,如 forEachmapfilter 等。而类数组对象没有这些原生的数组方法,它们的原型链与数组不同。这意味着如果我们想要对类数组进行类似数组的操作,需要额外的处理。
  2. 方法可用性 如前面所述,数组的方法可以直接使用,而类数组对象则不行。例如,尝试在 arguments 对象上直接调用 sort 方法会报错,因为它不存在于类数组的原型链上。

三、将类数组转换为数组

虽然类数组不是真正的数组,但在很多情况下,我们可能需要将其转换为数组以便使用数组的各种便利方法。有几种常见的转换方式:

  1. 使用 Array.from() 方法 Array.from() 方法可以将类数组对象或可迭代对象转换为真正的数组。例如:
function myFunction() {
  const argsArray = Array.from(arguments);
  return argsArray;
}
console.log(myFunction(1, 2, 3)); 

在上述代码中,arguments 这个类数组被成功转换为数组,我们就可以对其使用数组的各种方法了。 2. 使用 Array.prototype.slice.call()[].slice.call() 这种方式利用了 slice 方法可以作用于类数组对象的特性,返回一个新的数组。例如:

const domElements = document.getElementsByTagName('div');
const domArray = Array.prototype.slice.call(domElements);
console.log(domArray); 

这里将 getElementsByTagName 返回的类数组 domElements 转换为了真正的数组 domArray。 3. 使用扩展运算符 ... 扩展运算符...会将一个可迭代对象(类数组是可迭代对象)展开。它会遍历这个可迭代对象的元素,并将它们作为独立的元素放入一个新的数组中。例如,对于一个类数组对象,它会按照索引顺序将每个元素提取出来,组成一个真正的数组。

function myFunction() {
    const argsArray = [...arguments];
    return argsArray;
}
console.log(myFunction(1, 2, 3));

四、类数组的应用场景

  1. 函数参数处理 在函数中,arguments 类数组可以方便地获取传入的所有参数,即使参数数量不确定。通过将其转换为数组,我们可以更灵活地处理这些参数,比如进行参数的过滤、映射等操作。
  2. 处理 DOM 元素集合 当我们获取一组 DOM 元素时,如 document.querySelectorAll 返回的结果是类数组。将其转换为数组后,可以使用数组的迭代方法来批量操作这些 DOM 元素,使代码更加简洁和可读。