首頁  >  文章  >  web前端  >  NodeList 和 HTMLCollection 和 Array的解析

NodeList 和 HTMLCollection 和 Array的解析

不言
不言原創
2018-07-07 17:30:441936瀏覽

這篇文章主要介紹了關於NodeList 和HTMLCollection 和Array的解析,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下

Array,NodeList, HTMLCollection這三個概念和它們之間的關係有很多做了幾年前端的同學都搞不清楚,經常遇到但是又感覺很陌生,剪不斷理還亂的感覺。今天咱們就來理清這三個東西。

對於Array大家差不多都能弄明白,但是HTMLCollectio、NodeList和Array的關係好像總是很曖昧,有一點像但是又不那麼像,可能是我比較笨,但是真的被它們弄得很頭痛啊,所以今天下決心必須弄清楚它們。

咱們先不管那麼多概念和定義,先來看看這三個東西到底長什麼樣子。咱們先創建一個html文件,裡面就放三個嵌套的p:

nbsp;html>


    <meta>
    <meta>
    <meta>
    <title>Document</title>


    <p>
        p1
        </p><p>
            p2
            </p><p>
                p3
            </p>
        
    

NodeList

首先讓我們來研究一下NodeList,在瀏覽器中打開這個html文件,打開控制台輸入:

document.querySelectorAll('p')
列印結果

NodeList 和 HTMLCollection 和 Array的解析

我們發現傳回的NodeList包含這三個p。展開NodeList的__proto__屬性後發現,NodeList繼承於一個NodeList對象,而這個NodeList對象又繼承於Object對象。

NodeList除了length屬性外還有其他5個方法(method),分別是entries, forEach, item, keys, values,這五個方法都是做什麼用的呢?用一遍就知道:

entries():

呼叫entries方法會回傳一個iterator(迭代器),關於iterator/iterable可以參考MDN,簡單點說就是回傳了一個可以遍歷的對象,而這個物件實作了iterable protocal,所以需要用for...of遍歷,所以我們可以:

var ps = document.querySelectorAll('p');
for(var item of ps.entries()){
    console.log(item);
}

結果回傳了三個包含三個p物件陣列(為什麼不是三個key-value pair?),如圖:

NodeList 和 HTMLCollection 和 Array的解析

forEach():

#forEach的用法和Array的forEach用法一樣,都是用於遍歷集合元素:

var ps = document.querySelectorAll('p');
ps.forEach(function (el, index, list) {
    console.log(el);
});
item():

item()用於從NodeList中取得單一節點元素:

var ps = document.querySelectorAll('p');
console.log(ps.item(0));

列印結果:
NodeList 和 HTMLCollection 和 Array的解析

keys():

傳回一個iterator用於遍歷NodeList的key:

var ps = document.querySelectorAll('p');
for (var key of list.keys()) {
    console.log(key);
}

列印結果:
NodeList 和 HTMLCollection 和 Array的解析

#values():

keys()類似,回傳一個iterator用於遍歷NodeList的value,即html元素:

var ps = document.querySelectorAll('p');
for (var value of ps.values()) {
    console.log(value);
}

列印結果:
NodeList 和 HTMLCollection 和 Array的解析

透過對NodeList的研究我們發現,NodeList和Array沒有繼承關係,但都有length屬性和forEach方法,而且擁有幾個特有的方法,主要都是用來遍歷和取值用的。

HTMLCollection

認識了NodeList,我們再來認識HTMLCollection,同樣我們先取得到一個HTMLCollection,在控制台中輸入並執行:

document.getElementsByTagName('p')

列印結果:

NodeList 和 HTMLCollection 和 Array的解析

可以看到得到的HTMLCollection繼承於一個HTMLCollection對象,而HTMLCollection直接繼承於Object對象,所以它和NodeList是平階的。 HTMLCollection和NodeList一樣包含了查詢得到的html元素,length屬性和item方法,但沒有NodeList的entries, forEach, keys, values這四個方法,但又多了一個namedItem(根據id和name篩選元素)方法...

#看到了NodeList和HTMLCollection這兩個傢伙的真容,我們很好奇這兩個有很多相似又互相獨立的傢伙是怎麼發明出來的呢?什麼情況下得到的是NodeList,什麼情況是HTMLCollection呢?

MDN上是這麼介紹HTMLCollection的:

Note: This interface is called HTMLCollection for historical reasons (before the modern DOM, collections implementing this interface could only have HTML iteelements as the interface iteelements

翻譯一下就是:
之所以叫它HTMLCollection是因為某些歷史原因,在新一代DOM出現之前,實作HTMLCollection這個介面的集合只包含HTML元素,所以命名為HTMLCollection。

我们知道DOM节点(node)不光包含HTML元素,还包含text node(字符节点)和comment(注释),既然HTMLCollection只包含HTML元素,那NodeList是不是会包含所有类型的DOM节点呢,我们来试验一下,先写一段html:

<p>
    this is patent content
    </p><p>
        this is child content
    </p>
    <!-- this is comment -->

然后执行:

var parent = document.querySelector('.parent');
console.log(parent.childNodes);

打印结果:

NodeList 和 HTMLCollection 和 Array的解析

我们看到childNodes返回的是第一个p下面的所有DOM节点,包含3个text node(其中两个是换行符),一个子p,一个comment。这证实了我们对NodeList的猜想。

我们再看一下HTMLCollection,执行:

var parent = document.querySelector('.parent');
console.log(parent.children);

打印结果:

NodeList 和 HTMLCollection 和 Array的解析

只包含了子p,也验证了MDN上的说法。

至于parent即有childNodes属性,又有children属性呢?

因为parent即是一个Node对象(拥有childNodes属性),又因为它有子元素所以它又是一个ParentNode对象(拥有children属性)。

至此,我们对NodeList和HTMLCollection应该有一个比较全面的认识,总结一下就是HTMLCollection是比较早期的模型,只能包含HTML元素,早期就有的接口如document.getElementsByClassName, document.getElementsByTagName返回的就是HTMLCollection。NodeList是比较新的模型,相比HTMLCollection更加完善,不光有HTML元素,还有text节点和comment。比较新的接口如document.querySelectorAll返回的就是NodeList。

关于NodeList,HTMLCollection和Array的关系,就是长得像,有个别相似的功能,但是是完全不一样的东西。

当然关于HTMLCollection和NodeList的故事还没有讲完,因为它们有时候是live(活的?动态的?),有时候是not live(死的?静态的?),关于这个话题,之后的文章再详细分析。

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

相关推荐:

JavaScript创建对象的四种方式

浏览器与NodeJS的EventLoop异同以及部分机制

以上是NodeList 和 HTMLCollection 和 Array的解析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn