偽數組與可叠代對象
這兩者都可以通過Array.from(arrayLike[,mapFn[,thisArg]])
來返回一個數組。
偽數組
首先先得清楚對象和數組的差別:
- 對象的原型鏈上只有Object.prototype,而數組的原型鏈上有Array.prototype和Object.prototype
- 對象沒有length屬性,數組有,且自動更新
- 對象根據鍵值對取值,而數組根據序號取值
ok,接下來就可以引出偽數組了。
定義:
- 擁有length屬性,其他屬性為非負整數字符串(因為對象使用[]來取值,會將數值隱式轉換為字符串)
- 不具有數組具有的方法,即原型鏈上沒有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)
方法有:
- m.get(鍵)可以得到對應的值
- m.set(鍵,值)來新添一維數組,如果鍵名重復的話,覆蓋原先的。如果只有一個參數,則值為undefined
- m.has(鍵)來確定是否存在這個鍵
- m.delete(鍵)來刪除一維數組成員
Set
Set和數組相對應,他的出現是為了解決數組中重復成員的問題。
創建一個Set。需要提供一個一維數組作為輸入,重復的元素在Set中自動被過濾。(註意,他的格式依然是個{}格式,而不是數組格式,格式如下Set { 2323, 23423, ‘sfsdfsfs‘ }
)
方法:
- s.add(值)來添加Set對象成員
- s.delete(值)來刪除成員
- s.has(值)
- 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好用
偽數組與可叠代對象