1. 程式人生 > >偽數組與可叠代對象

偽數組與可叠代對象

屬性 dom 不能 type ber 會有 輸入 asd 鍵值對

這兩者都可以通過Array.from(arrayLike[,mapFn[,thisArg]])來返回一個數組。

偽數組

首先先得清楚對象和數組的差別:

  1. 對象的原型鏈上只有Object.prototype,而數組的原型鏈上有Array.prototype和Object.prototype
  2. 對象沒有length屬性,數組有,且自動更新
  3. 對象根據鍵值對取值,而數組根據序號取值

ok,接下來就可以引出偽數組了。

定義:

  1. 擁有length屬性,其他屬性為非負整數字符串(因為對象使用[]來取值,會將數值隱式轉換為字符串)
  2. 不具有數組具有的方法,即原型鏈上沒有Array.prototype

內容如下:

var fakeArray = {
    length: 3,
    "0": "first",
    "1": "second",
    "2": "third"
};

偽數組是個對象(所以沒有Array.prototype的屬性值),但他和數組一樣擁有length,數值屬性下標,從外觀上看偽數組,看不出他和數組的區別。

偽數組的意義就是:讓普通對象也可以正常使用數組的很多方法。

大名鼎鼎的偽數組有:arguments對象,DOM的childNodes。

我們通過Array.isArray()來判斷其是否為數組。

可叠代對象

在學習可叠代對象之前,我們先來學習ES6新引入的Map和Set數據類型。

Map

Map相對應的是Object對象,兩者都是鍵值對結構。(註意,他的格式依然是{}格式,而不是數組格式,格式如下Map { 2323 => 23423, ‘sdfasdf‘ => 234234, 324 => ‘sfsdfas‘ }

但是Object對象有一個小問題,即Object的鍵必須得是字符串,但實際上Number或者其他數據類型作為鍵也是十分合理的。

為了解決這個問題,最新的ES6引入了新的數據類型Map。

Map通過一個二維數組來定義。

var m = new Map([[100,‘sdfsd‘],[35,‘dsfdsf‘]])

,其中每個數組中的第一個是鍵,第二個是值

但是,註意,要想獲得Map的值不能像對象一樣直接訪問,需要使用set來添加鍵值對,通過get來得到值(通過has來判斷是否有這個key)

方法有:

  1. m.get(鍵)可以得到對應的值
  2. m.set(鍵,值)來新添一維數組,如果鍵名重復的話,覆蓋原先的。如果只有一個參數,則值為undefined
  3. m.has(鍵)來確定是否存在這個鍵
  4. m.delete(鍵)來刪除一維數組成員

Set

Set和數組相對應,他的出現是為了解決數組中重復成員的問題。

創建一個Set。需要提供一個一維數組作為輸入,重復的元素在Set中自動被過濾。(註意,他的格式依然是個{}格式,而不是數組格式,格式如下Set { 2323, 23423, ‘sfsdfsfs‘ })

方法:

  1. s.add(值)來添加Set對象成員
  2. s.delete(值)來刪除成員
  3. s.has(值)
  4. Set無法單獨取成員,因為其既沒有下標,又沒有鍵值對,所以沒有辦法取到單個成員

iterable

Map,Set,Array的作用是一致的,都是為了保存一組數據,所以這三者都屬於iterable類型(因為數據都是叠代存儲的,所以存儲在叠代器中)。而我們往往會有這麽一個需求:遍歷這一組數據。

Array可以使用for循環遍歷,但是因為Set,Map沒有下標,所以無法使用for循環遍歷。

所以,我們創建了一個新的方法:for..of來遍歷,for..of著眼的不再是下標,而是每個叠代對象,Array的叠代對象是單值,Map的叠代對象是一維數組,Set的叠代對象也是單值。

切記,for..in不能用於叠代內容,他僅能用於Array的叠代下標及Object的叠代屬性,而Map,Set都是不能使用這個for..in,能且僅能使用for..of。

然而,更好的方式是直接使用iterable內置的forEach()方法,他接受一個函數,每次叠代就自動回調該函數。

Array:

var a = ['A', 'B', 'C'];
a.forEach(function(element,index,array){//第一個參數是當前元素的值,第二個參數是當前索引,第三個參數指向Array對象本身
    
    console.log(element)
    console.log(index)
    console.log(array)
    

})

Map:

var m = new Map([[2323,23423],['sdfasdf',234234],[324,'sfsdfas']])

m.forEach(function(value,key,map){//第一個參數是當前數組的值,第二個參數當前數組的鍵,第三個指向Map對象本身
    console.log(value)
    console.log(key)
    console.log(map)

})

Set:

var m = new Set([2323,23423,'sfsdfsfs'])
console.log(m)
m.forEach(function(element,sameElement,Set){//第一個是當前元素的值,第二個也是當前元素的值,第三個是指向Set對象本身
    console.log(element)
    console.log(sameElement)
    console.log(Set)

})

記憶技巧:

for(var i=0;i<9;i++):僅能用於Array及偽數組。因為這個方法要求有length屬性及下標,只有Array和偽數組有

for..in:僅能用於Array,Object,結果是叠代屬性(for (var item in Array))

for..of:僅能用於Array,Map,Set。這個方法是叠代器的專屬,而只有這三者是叠代器,Object不是叠代器,結果是叠代內容(for(var item of Set))

forEach(function):是叠代器的方法,因為參數的豐富性,所以比for..of好用

偽數組與可叠代對象