类数组对象解析

作者: color_小浣熊 | 来源:发表于2018-12-29 09:34 被阅读1次

一、定义

数组定义:简而言之就是一组有序的数据集合,其索引为从0开始且自然增长的整数,其元素值可以是任何js数据!并且包含一个名为length的属性,该属性表示数组元素的个数。

var array = [1,2,3];
console.log(array[0])//1
​console.log(array[1])//2
​console.log(array[2])//3
​console.log(array['length'])//3

从上面的例子我们可以看到,在声明数组时,我们只是显式的声明了数组元素的值,并没有显式的给这些值定义索引和length属性,但是在数组定义好后我们发现就可以直接使用数组的索引值来操作数组的元素了,从这不难看出,数组元素的索引和length属性是在数组定义时根据数组元素语言自动就帮你定义好了!而且很容易就能看出来,索引值是从0开始并且自然递增的!
对象定义:js中对象类型为一组无序的由键->值组成的数据集合,其元素的键名和值都可以自定义!

var object = {'a': 1, 'b': 2}
console.log(object['a'])//1
console.log(object['b'])//2
console.log(object['length'])//undefined

从上面的例子简单来看,对象自身所拥有的(不包括继承来的)任何属性都是有用户自定义的,所以要想获得length我们可以显式的给对象定义length属性

var arr = [1,2,3];
var obj = {0: 1, 1: 2, 2: 3, length: 3};//类数组对象
console.log(arr[0], obj[0])//1, 1
console.log(arr['length'], obj['length'])//3, 3

类数组对象:只包含使用从零开始,且自然递增的整数做键名,并且定义了length表示元素个数的对象,我们就认为他是类数组对象!

二、类数组对象的表现形式:NodeList(动态集合、静态集合)、HTMLCollection(动态集合)、NamedNodeMap(动态集合)

动态集合指的是DOM结构发生变化能够自动的反映到所保存的对象中,而静态集合当DOM发生变化时,之前保存的类数组并没有发生变化;

NodeList是节点的集合,HTMLCollection是元素节点的集合,NamedNodeMap是特性节点的集合,它们都是类数组对象

用于本次文章的代码结构(html)组成部分

    <div id="nodes">
        <P class="node_p">第一个p</P>
        <P class="node_p">第二个p</P>
        <P class="node_p">第三个p</P>
    </div>
  1. NodeList:指类数组对象,他的成员组成为节点对象,包括通过childNodes返回的动态集合和通过querySelector()方法返回的静态集合
  • childNodes获取(动态)类数组对象分析:
let childNodes = document.getElementById('nodes').childNodes
    console.log(childNodes)
    document.getElementById('nodes').appendChild(document.createElement('input')) //DOM发生改变
    console.log(childNodes)

控制台显示


image.png

可以看出在动态增加了DOM的时候,类数组集合是动态增加的

  • querySeletorAll()获取(静态)类数组对象分析:
let nodeList = document.querySelectorAll('p')
    console.log(nodeList)
    document.getElementById('nodes').appendChild(document.createElement('input')) //DOM发生改变
    console.log(nodeList)

控制台输出:


image.png
  1. HTMLCollection(动态集合)
  • 与NodeList对象类似,也是节点的集合,返回一个类数组对象;

  • NodeList集合主要是Node节点的集合,而HTMLCollection集合主要是Element元素节点的集合。Node节点共有12种,Element元素节点只是其中一种。关于12种节点类型的详细信息移步至此

  • HTMLCollection集合包括getElementsByTagName()、getElementsByClassName()、getElementsByName()等方法的返回值,以及children、document.links、document.forms等元素集合

let HtmlCollection = document.getElementsByTagName('p')
    console.log(HtmlCollection)
    document.getElementById('nodes').appendChild(document.createElement('p')) //DOM发生改变
    console.log(HtmlCollection)

控制台输出:


image.png
  1. NamedNodeMap(动态集合);对象的常见实例对象是attributes属性
let namedNodes = document.getElementById('nodes').attributes;
    console.log(namedNodes)
    document.getElementById('nodes').setAttribute('class','nodes') //DOM发生改变
    console.log(namedNodes)

控制台输出:


image.png

三、注意事项

  1. 由于NodeList、HTMLCollection、NamedNodeMap是类数组对象,并不是真正的数组对象,可以使用slice()方法或者Array.from()方法将其变成真正的数组
let namedNodes = document.getElementById('nodes').attributes;
    console.log(namedNodes)
    document.getElementById('nodes').setAttribute('class','nodes') //DOM发生改变
    console.log(namedNodes)
    console.log(Array.prototype.slice.call(namedNodes))
    console.log(Array.from(namedNodes))//方法从一个类似数组或可迭代对象中创建一个新的数组实例。

控制台输出:


image.png
  1. 由于IE8-浏览器将NodeList实现为一个DOM对象,不能使用Array.prototype.slice()方法,必须手动枚举所有成员
<div id="test"></div>
<script>
var childN = test.childNodes;
console.log(childN instanceof Array);//false
function convertToArray(nodes){
    var array = null;
    try{
        array = Array.prototype.slice.call(nodes)
    }catch(ex){
        array = [];
        var len = nodes.length;
        for(var i = 0; i < len; i++){
            array.push(nodes[i]);
        }
    }
    return array;
}
var childNew = convertToArray(childN);
console.log(childNew instanceof Array);//true
</script>
  1. 在实际运用中,涉及用动态集合循环的时候要注意,由于他的集合是动态的,所以他的长度是随之变化的饿,易造成死循环。
let HtmlCollection = document.getElementsByTagName('p')
    console.log(HtmlCollection)
    
    for(var i =0;i<HtmlCollection.length;i++){
        document.getElementById('nodes').appendChild(document.createElement('p')) //DOM发生改变
        console.log(HtmlCollection.length)
    }

控制台输出:

image.png
解决办法把他的长度定义出来,再使用:
let HtmlCollection = document.getElementsByTagName('p')
    console.log(HtmlCollection)
    var length = HtmlCollection.length
    for(var i =0;i<length;i++){
        document.getElementById('nodes').appendChild(document.createElement('p')) //DOM发生改变
        console.log(length)
        console.log(HtmlCollection.length)
    }

控制台:


image.png

友情链接地址:

本文借鉴:1、 深入理解javascript中的动态集合——NodeList、HTMLCollection和NamedNodeMap
2、 js之数组,对象,类数组对象

相关文章

  • 类数组对象解析

    一、定义 数组定义:简而言之就是一组有序的数据集合,其索引为从0开始且自然增长的整数,其元素值可以是任何js数据!...

  • 面向对象

    面向过程与面向对象: 内存解析 对象数组的内存解析 匿名对象

  • 对Javascript 类数组对象的理解与应用 | Argume

    这篇文章将要告诉你: 什么是类数组对象 类数组对象是如何出现的 如何避免使用类数组对象的常见问题 将类数组对象转换...

  • 类数组、arguments

    arguments为一个类数组的对象;类数组对象即为:有length属性和索引的对象。一、类数组===》数组var...

  • JS之类数组对象以及转换方法大全

    什么是类数组对象 有length属性和若干索引属性的对象。 为什么叫类数组 类数组对象可以执行一些常见的数组操作,...

  • 类数组对象与arguments

    原文出处 JavaScript深入之类数组对象与arguments 类数组对象 所谓的类数组对象: 拥有一个 le...

  • ES6对数组的扩展

    Array.from() Array.from方法用于将“类数组”对象和“可迭代”对象转为真正的数组。 类数组对象...

  • 对象(实例)与类、变量、实例方法与类方法

    一、对象(实例)与类: 类表示对象的类型,有数组类、字符串类。如: [1,2,3]是一个数组对象,属于数组Arra...

  • 类数组与数组

    数组和类数组对象有什么区别数组和类数组对象都可以用索引访问,并具有length属性,不同是类数组不能调用数组的方法...

  • JS 中的类数组对象如何转换为数组?

    大家好,我是前端西瓜哥,今天说一下 JS 的类数组对象是什么,以及如何将类数组对象转为数组。 类数组对象是什么? ...

网友评论

    本文标题:类数组对象解析

    本文链接:https://www.haomeiwen.com/subject/pzvelqtx.html