JavaScript中的稀疏數(shù)組與密集數(shù)組[譯]
創(chuàng)建一個(gè)指定長(zhǎng)度的稀疏數(shù)組很簡(jiǎn)單:
> var a = new Array(3);
> a
[ , , ]
> a.length
3
> a[0]
undefined
當(dāng)你遍歷它時(shí),你會(huì)發(fā)現(xiàn),它并沒(méi)有元素.JavaScript會(huì)跳過(guò)這些縫隙.
> a.forEach(function (x, i) { console.log(i+". "+x) });
> a.map(function (x, i) { return i })
[ , , ]
譯者注:還有一些其他情況會(huì)生成稀疏數(shù)組,比如
>var arr = [];
>arr[0] = 0;
>arr[100] = 100>a.forEach(function (x, i) { console.log(i+". "+x) });0. 0100. 100
2.密集數(shù)組
Brandon Benvie 最近在es-discuss郵件討論組中提到了一個(gè)創(chuàng)建密集數(shù)組的技巧:
> var a = Array.apply(null, Array(3));
> a
[ undefined, undefined, undefined ]
上面的語(yǔ)句其實(shí)等同于:
Array(undefined, undefined, undefined)
但從表面上看,貌似這個(gè)數(shù)組和之前的稀疏數(shù)組并沒(méi)有太多的區(qū)別:
> a.length
3
> a[0]
undefined
可是,你現(xiàn)在可以遍歷到這些數(shù)組元素了,還可以為每個(gè)元素重新賦值:
> a.forEach(function (x, i) { console.log(i+". "+x) });
0. undefined
1. undefined
2. undefined
> a.map(function (x, i) { return i })
[ 0, 1, 2 ]
譯者注:實(shí)際上,JavaScript并沒(méi)有常規(guī)的數(shù)組,所有的數(shù)組其實(shí)就是個(gè)對(duì)象,只不過(guò)會(huì)自動(dòng)管理一些"數(shù)字"屬性和length屬性罷了.說(shuō)的更直接一點(diǎn),JavaScript中的數(shù)組根本沒(méi)有索引,因?yàn)樗饕龖?yīng)該是數(shù)字,而JavaScript中數(shù)組的索引其實(shí)是字符串.arr[1]其實(shí)就是arr["1"],給arr["1000"] = 1,arr.length也會(huì)自動(dòng)變?yōu)?001.這些表現(xiàn)的根本原因就是,JavaScript中的對(duì)象就是字符串到任意值的鍵值對(duì).注意鍵只能是字符串.這和AWK類(lèi)似.不信可以試試awk 'BEGIN{a[1]=1;print(a["1"])}'.也許這是因?yàn)?A target=_blank>Brendan Eich在發(fā)明JavaScript時(shí)參考了不少awk的設(shè)計(jì)的原因.不過(guò)目前,ES6中已經(jīng)有了類(lèi)似于Java等語(yǔ)言的Map類(lèi)型,鍵可以是任意類(lèi)型的值.請(qǐng)參考我翻譯的MDN文檔Map
3.另一個(gè)技巧
郵件里還提到了另外一個(gè)技巧:
> Array.apply(null, Array(3)).map(Function.prototype.call.bind(Number))
[ 0, 1, 2 ]
這大概等同于下面的寫(xiě)法
Array.apply(null, Array(3)).map(
function (x,i,...) { return Number.call(x,i,...) })
注意,x是call方法的第一個(gè)參數(shù),它作為了Number函數(shù)中的this值.這個(gè)值沒(méi)有什么意義,相當(dāng)于被忽略.我更喜歡下面這個(gè)能讓人一眼就看明白的寫(xiě)法:
Array.apply(null, Array(3)).map(function (x,i) { return i })
譯者注:
Array.apply(null, Array(3)).map(Function.prototype.call.bind(Number))
//等同于Array.apply(null, Array(3)).map(Function.prototype.call,Number)
雖然使用自定義的函數(shù)更清晰,但自定義的函數(shù)肯定沒(méi)有原生方法快.舉個(gè)例子:
var a = ["aaa ", " bbb", " ccc "]
a.map(function(x) { return x.trim(); }); // ['aaa', 'bbb', 'ccc']
a.map(Function.prototype.call, String.prototype.trim); // ['aaa', 'bbb', 'ccc']
上面使用map方法來(lái)trim掉每個(gè)數(shù)組元素的空格,使用原生的方法雖然難理解.但效率高.看不懂的可以查看下我翻譯的MDN文檔Array.prototype.map()
4.實(shí)際用途?
在實(shí)際生產(chǎn)中,使用上面講的創(chuàng)建密集數(shù)組的方法會(huì)讓別人無(wú)法讀懂你的代碼.所以封裝成一個(gè)工具函數(shù)會(huì)更好,比如 _.range:
> _.range(3)
[ 0, 1, 2 ]
和map配合使用,可以使用某個(gè)指定的值填充整個(gè)數(shù)組.
> _.range(3).map(function () { return "a" })
[ 'a', 'a', 'a' ]
譯者注:其他語(yǔ)言里,都有方便的生成遞增數(shù)字列表的辦法,比如perl和ruby里使用1..100,python里使用range(100),還有一個(gè)常見(jiàn)的需求就是生成一個(gè)重復(fù)某個(gè)字段的字符串,在ruby和python里,可以用"a"*100,在perl里用"a"x100,在JavaScript中,可以用Array(100).join("a")
5.相關(guān)文章
相關(guān)文章
javascript實(shí)現(xiàn)模擬時(shí)鐘的方法
這篇文章主要介紹了javascript實(shí)現(xiàn)模擬時(shí)鐘的方法,涉及javascript操作時(shí)間實(shí)時(shí)顯示的相關(guān)技巧,需要的朋友可以參考下2015-05-05javascript 如何生成不重復(fù)的隨機(jī)數(shù)
javascript 如何生成不重復(fù)的隨機(jī)數(shù)...2007-11-11前端強(qiáng)大的圖片預(yù)覽組件Viewer.js使用方法
這篇文章主要給大家介紹了關(guān)于前端強(qiáng)大的圖片預(yù)覽組件Viewer.js使用方法的相關(guān)資料,Viewer.js是一款強(qiáng)大的圖片查看器,雖然簡(jiǎn)單且易上手,但是卻并不影響其在圖片查看方面的強(qiáng)大功能,同時(shí)這款優(yōu)秀的插件配置操作起來(lái)也非常的方便,需要的朋友可以參考下2024-01-01TypeScript中的交叉類(lèi)型和聯(lián)合類(lèi)型示例講解
交叉類(lèi)型簡(jiǎn)單來(lái)說(shuō)就是通過(guò)&符號(hào)將多個(gè)類(lèi)型進(jìn)行合并成一個(gè)類(lèi)型,然后用type來(lái)聲明新生成的類(lèi)型,聯(lián)合類(lèi)型和交叉類(lèi)型比較相似,聯(lián)合類(lèi)型通過(guò)|符號(hào)連接多個(gè)類(lèi)型從而生成新的類(lèi)型,本文就這兩個(gè)類(lèi)型結(jié)合示例代碼詳細(xì)講解,感興趣的朋友跟隨小編一起學(xué)習(xí)吧2022-12-12