FE class 3 of hunger Valley 葉世清
童鞋們在平時可能會遇到類數(shù)組Array-like谎痢,它和數(shù)組很像,但是就是沒法用到數(shù)組的一些方法卷雕,真討厭节猿,所以我們通常要轉(zhuǎn)換成數(shù)組才行。
一漫雕、什么是類數(shù)組ArrayLike?
興趣先行滨嘱,我們舉一個比較經(jīng)典的類數(shù)組(最經(jīng)典的類數(shù)組是Arguments,這里暫且不說)浸间。
var nodeList=document.querySelectorAll("div");這個nodeList就是一個類數(shù)組太雨。何以見得?它可以用nodeList[0]取到第一個子元素魁蒜。但是當我們用console.log(nodeList instanceof Array)返回false也就是說它并不是數(shù)組的實例囊扳,也就不是數(shù)組。
ArrayLike對象的精妙在于它和javascript原生的Array類似兜看,但是它是自由構(gòu)建的锥咸,它來自開發(fā)者對javascript對象的擴展,也就是說:對于它的原型(prototype)我們可以自由定義细移,而不會污染到j(luò)avascript原生的Array搏予。
二、類數(shù)組轉(zhuǎn)換為數(shù)組之后進行操作有什么優(yōu)勢弧轧?
1.首先考慮性能方面的優(yōu)勢雪侥,我做了個實驗。請戳 ??性能比較:點擊按鈕進行遍歷
實驗結(jié)論:直接用for循環(huán)遍歷和數(shù)組轉(zhuǎn)換為類數(shù)組之后進行遍歷精绎,優(yōu)勢并不明顯校镐。反而感覺有劣勢,但影響不大捺典。
2.其次鸟廓,既然性能沒有增強,為什么要實現(xiàn)類數(shù)組轉(zhuǎn)換為數(shù)組襟己?
簡而言之:使得該對象具有更多有益API引谜。
Array在js里面是非常強大有用的,它有很多方法:shift,unshift,splice,slice,concat,reverse,sort擎浴。ECMAscript 2015又新增了一些方法forEach,isArray,indexOf,lastIndexOf,every,some,map,filter,reduce等等员咽。包括那個IT笑話,“對程序員來說push的反義詞是pop(^_^)”? 說的都是和數(shù)組相關(guān)的贮预。但是這些強大的方法贝室,類數(shù)組是不一定全部支持的契讲。當我們需要進行數(shù)組屬性操作的時候才發(fā)現(xiàn),啊原來這是個類數(shù)組滑频,啊捡偏,要是能變成數(shù)組多好啊,否則我還得自己寫峡迷。雖然每一種方法都是可以自己靠基礎(chǔ)api實現(xiàn)的银伟,但是每次都做重復的基礎(chǔ)工作,多枯燥绘搞。學會偷懶有時候能幫助提高效率~~
三彤避、轉(zhuǎn)換方式:Array.prototype.slice.call(arrayLike)
首先Array.prototype.slice.call(arrayLike)的結(jié)果是將arrayLike對象轉(zhuǎn)換成一個Array對象。所以其后面可以直接調(diào)用數(shù)組具有的方法夯辖。譬如
Array.prototype.slice.call(arrayLike).forEach(function(element,index){ ?
//可以隨意操作每一個element了
})
解析點1:Array.prototype.slice表示數(shù)組的原型中的slice方法琉预。注意這個slice方法返回的是一個Array類型的對象(這句話很多分析的文章沒有點破,我就問了憑什么非得是slice啊?原因就在這)蒿褂。splice行不行呢圆米?Array.prototype.splice.call(arrayLike,0)這種形式也可以。只要返回的是原數(shù)組就可以贮缅。當然,那種寫法更省事一目了然介却。
解析點2:能調(diào)用call的只有方法谴供,所以不能用[].call這種形式,得用[].slice齿坷。而call的第一個參數(shù)表示真正調(diào)用slice的環(huán)境變?yōu)榱薬rrayLike對象桂肌。所以就好像arrayLike也具有了數(shù)組的方法。
附錄:
ECMAScript6 API瀏覽器相關(guān)兼容性可見(不過個人感覺永淌,沒有CANIUSE好用) http://kangax.github.io/compat-table/es6/
今日勵志感言:不積跬步無以至千里崎场,不積小流無以成江海——貴在堅持遂蛀!