類數組對象解析


一、定義

數組定義:簡而言之就是一組有序的數據集合,其索引為從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之數組,對象,類數組對象


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM