你还傻傻分不清JS中“类数组“和‘’数组‘’的区别吗?

563 阅读3分钟

前言

在JavaScript中,我们经常遇到一些对象看起来像数组但又不是真正的数组。这些对象被称为“类数组”(Array-like)对象。它们具有某些数组的特性,但缺乏数组的所有方法。本文将结合实例带你分析,彻底搞懂!

本文要想切底理解还得知道一些原型和构造函数的知识。此文JS中的“暧昧”三角:构造函数、原型与实例对象的隐秘关联引言: 今天刚拿到小黄书,就翻到了第二部分,别误会哦!我看的是你 - 掘金 能给你提供一些帮助。

什么是类数组对象?

类数组对象通常指的是那些拥有length属性,并且可以通过索引来访问元素的对象。然而,它们并不是由Array构造函数创建的,因此不继承自Array.prototype,也就没有数组的原生方法,例如pushpopmap等。

常见的类数组对象包括:

  • arguments 对象
  • NodeList 和 HTMLCollection 对象 今天重点拿 NodeList 和 HTMLCollection 对象来进行分析:

NodeList 和 HTMLCollection

在DOM操作中,我们经常使用document.getElementsByTagNamedocument.querySelectorAll来获取元素集合。这两个方法返回的结果分别是HTMLCollectionNodeList,它们都是类数组对象。

讲解案例:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>类数组</title>
</head>
<body>
  <!-- p{这是第$个段落}*10 -->
  <p>这是第1个段落</p>
  <p>这是第2个段落</p>
  <p>这是第3个段落</p>
  <p>这是第4个段落</p>
  <p>这是第5个段落</p>
  <p>这是第6个段落</p>
  <p>这是第7个段落</p>
  <p>这是第8个段落</p>
  <p>这是第9个段落</p>
  <p>这是第10个段落</p>
  <script>
  const nodeList = document.getElementsByTagName('p');
  const nodeArr = document.querySelectorAll('p');
  console.log(nodeList, nodeArr);
 
  </script>
</body>
</html>

- 首先通过调用 document.getElementsByTagName('p') 和document.querySelectorAll('p') 分别获得了两个类数组为nodeList,nodeArr,也是两个实例化对象,我们可以调用 xxx.__proto__.constructor来看看它们对象的类型如何?

结果: 一个是 NodeList,另一个是 HTMLCollection,弄明白它们的对象不同之后。 image.png

和数组的相似之处:

添加下面这行代码:

nodeArr.forEach(node => {
    console.log(node.__proto__.constructor);
  })
   nodeList.forEach(node => {
    console.log(node.__proto__.constructor);
  })

结果: 我们可以看到,nodeArr像数组一样进行了遍历,而另一个虽然也是类数组,但是人与人之间是有差距的它并没有foreach这个方法

image.png

最后 我们可以调用方法nodeArr.proto 和 nodeList.proto,来看看这两个对象里面有哪些方法:

image.png

和数组的区别之处:

其实看完这些方法,我们就基本知道它和数组的区别的哪儿了,它的方法远没有数组那么多

nodeList.join(',')

比如我们调用这个方法,就会报错,因为nodeList没有这个方法,当然不能执行了。

展示一下真正数组的方法,就展现出差距了。

image.png

类数组对象的特点

  1. 长度属性: 类数组对象通常有一个 length 属性,表示其中包含的元素数量。

    const paragraphs = document.querySelectorAll('p');
    console.log(paragraphs.length); // 输出段落数量
    
  2. 索引访问: 类数组对象可以通过索引访问其元素。

    
    const paragraphs = document.querySelectorAll('p');
    console.log(paragraphs[0]); // 输出第一个段落
    
  3. 非数组方法: 类数组对象不支持数组的方法,如 pushpopmap 等。

    const paragraphs = document.querySelectorAll('p');
    // 下面的代码会报错
    // paragraphs.push(newParagraph);
    

最后来讲讲转换类数组为数组

来讲讲ES6中新引入的一个运算符: ...

const paragraphs = document.querySelectorAll('p'); 
const paragraphsArray = [...paragraphs]; 
console.log(Array.isArray(paragraphsArray)); // true
paragraphsArray.join(",")

如果本文对你有帮助,也请点个赞呢!有问题也请指教