类数组对象解析

一、定义

数组定义:简而言之就是一组有序的数据集合,其索引为从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之数组,对象,类数组对象

posted @ 2018-12-29 09:44  color_小浣熊  阅读(1960)  评论(0编辑  收藏  举报
百度