JavaScript 之动态集合

作者: 贵在随心 | 来源:发表于2017-09-17 21:53 被阅读99次

第一次读《JavaScript高级程序设计(第三版)》,没怎么注意和理解JavaScript 动态集合的概念,最近二次阅读这本书,想进一步对其做深入的研究。现于此细究一下这三个动态集合(HTMLCollection、NodeList、NodeNameMap)之间的用法和联系及区别。

这里的动态集合是指:DOM结构的变化能够自动反应到所保存的对象中。

NodeList

NodeList 是一种类数组对象,是node节点(12种)的集合,用于保存一组有序的节点,可以通过节点的位置访问这些节点。在childNodes属性和querySelectorAll()方法返回值中保存着 NodeList 对象。

在childNodes属性中的NodeList对象

var div = document.getElementById("div1");
var children = div.childNodes;         //获取div元素子节点集合
alert(children instanceof NodeList);   //true

通过querySelectAll()方法返回值中的NodeList对象

var divs = documene,qrerySelectAll('div');
alert(divs.instance of NodeList)  //true

这里需要注意的是通过querySelectorAll()方法返回值中保存着 NodeList 对象是静态集合;这里可以与下文中的HTMLCollection 对象作为对比,如下图所示:

33.png

如此就可以看出两者之间“动态”和“静态”的区别。

HTMLCollection

HTMLCollection对象与NodeList对象类似,都是节点的集合,返回的都是类数组对象。但他们也存在着不同之处:NodeList集合包含着node节点中12种节点,而HTMLCollection 仅包含elements 元素节点的集合。

HTMLCollection对象包含于getElemenstByTagName()、getElementsByClassName()、getElementsByName()等方法返回的值,以及children、document.links、document.forms等元素集合。

<div id="test"></div>
<script>
var childN = test.children;
//IE7-浏览器并未定义HTMLCollection对象,会报错,其他浏览器返回true
alert(childN instanceof HTMLCollection);
var tags =test.getElementsByTagName('div');
//IE7-浏览器并未定义HTMLCollection对象,会报错,其他浏览器返回true
alert(tags instanceof HTMLCollection);
</script> 

NameNodeMap

这个对象包含于attributes 属性中,元素的每一个特性都由一个Attr 节点表示,每个节点都保存在 NameNodeMap 对象中。

var div = document.getElementById("div1");
var attrs = div.attributes;            //获取div元素的特性
alert(children instanceof NamedNodeMap);  //true

类数组转数组的方法

之前了解 arguments 对象的都知道,它是一个类数组对象,有数组的表达方式,但并没有数组方法。而HTMLCollection、NodeList、NodeNameMap 这三者同样与 arguments 对象一样。因此必须将其实现由类数组转化为数组:

function convertToArray(nodes) {
    var array = null;
    try {
        array = nodes.prototype.slice.call(nodes, 0);
    } catch {  
//由于IE8-浏览器将NodeList实现为一个COM对象,不能使用Array.prototype.slice()方法,必须手动枚举所有成员。
       array = new Array();
       for(var i = 0, len =  nodes.length; i <len; i++) {
                array.push(nodes[i]);
            }
        }
    }
var ff = convertToArray(nodes);
console.log(ff instanceof Array);  //true

因DOM操作是往往是JavaScript 程序中开销最大的部分,因此在循环遍历这些动态集合时,不要忽略其动态性,从而避免穿死循环,如下两段代码对比:

var divs = document.getElementsByTagName("div");
for(var i = 0 ; i < divs.length; i++){
 document.body.appendChild(document.createElement("div"));
}

在上面代码中,由于divs是一个HTMLElement集合,divs.length会随着appendChild()方法,而一直增加,于是变成一个死循环。
为了避免此种情况发生,代码改进如下:

var divs = document.getElementsByTagName("div");
for(var i = 0,len = divs.length; i < len; i++){
 document.body.appendChild(document.createElement("div"));
}

一般地,要尽量减少访问NodeList、HTMLCollection、NamedNodeMap的次数。因为每次访问它们,都会运行一次基于文档的查询。所以,可以考虑将它们的值缓存起来。

对于JavaScript 的动态集合就总结这么多,若有纰漏方请指正,后期后跟进补充其它的JavaScript 内容。

相关文章

  • JavaScript 之动态集合

    第一次读《JavaScript高级程序设计(第三版)》,没怎么注意和理解JavaScript 动态集合的概念,最近...

  • DOM动态集合

    DOM是JavaScript中重要部分之一,在DOM中有一个动态集合。 这个动态集合包含节点的集合(NodeLis...

  • JavaScript深入系列的学习(一)

    JavaScript深入之从原型到原型链JavaScript深入之词法作用域和动态作用域JavaScript深入之...

  • 2019-05-30

    Javascript之动态加载脚本和样式 //动态加载脚本 function loadScript(url){ ...

  • 客户端的JavaScript(四)

    JavaScript的动态集合 之前讲了一点NodeList对象,HTMLCollection对象,一般情况下qu...

  • JavaScript 动态创建 Form 表单

    本文主要介绍了 JavaScript 动态创建 Form 表单并提交的实现方法,涉及 JavaScript 动态创...

  • JS-Basic

    本文主要结构 任务JavaScript基础练习JavaScript集合练习 JavaScript基础练习学到的主要...

  • Javascript 集合

    集合的特点是不包含重复元素,集合的元素通常无顺序之分。在系统编程中集合很常用,但是并非所有语言都原生支持集合。集合...

  • JS 数组

    1.JavaScript中数组的特点 数组长度可以动态改变。 同一个数组中可以存储不同的数据类型。 数据的有序集合...

  • JavaScript练习

    github地址: JavaScript基础练习basic practice 1 JavaScript集合练习pr...

网友评论

    本文标题:JavaScript 之动态集合

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