JavaScript中的稀疏數組與密集數組[譯]

來源:互聯網
上載者:User

1.稀疏數組
建立一個指定長度的稀疏數組很簡單: 複製代碼 代碼如下:> var a = new Array(3);
> a
[ , , ]
> a.length
3
> a[0]
undefined

當你遍曆它時,你會發現,它並沒有元素.JavaScript會跳過這些縫隙. 複製代碼 代碼如下:> a.forEach(function (x, i) { console.log(i+". "+x) });
> a.map(function (x, i) { return i })
[ , , ]

譯者注:還有一些其他情況會產生稀疏數組,比如 複製代碼 代碼如下:>var arr = [];
>arr[0] = 0;
>arr[100] = 100>a.forEach(function (x, i) { console.log(i+". "+x) });0. 0100. 100

2.密集數組

Brandon Benvie 最近在es-discuss郵件討論群組中提到了一個建立密集數組的技巧:

複製代碼 代碼如下:> var a = Array.apply(null, Array(3));
> a
[ undefined, undefined, undefined ]

上面的語句其實等同於:

Array(undefined, undefined, undefined)

但從表面上看,貌似這個數組和之前的稀疏數組並沒有太多的區別:複製代碼 代碼如下:> a.length
3
> a[0]
undefined

可是,你現在可以遍曆到這些數組元素了,還可以為每個元素重新賦值: 複製代碼 代碼如下:> 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 ]

譯者注:實際上,JavaScript並沒有常規的數組,所有的數組其實就是個對象,只不過會自動管理一些"數字"屬性和length屬性罷了.說的更直接一點,JavaScript中的數組根本沒有索引,因為索引應該是數字,而JavaScript中數組的索引其實是字串.arr[1]其實就是arr["1"],給arr["1000"] = 1,arr.length也會自動變為1001.這些表現的根本原因就是,JavaScript中的對象就是字串到任意值的索引值對.注意鍵只能是字串.這和AWK類似.不信可以試試awk 'BEGIN{a[1]=1;print(a["1"])}'.也許這是因為Brendan Eich在發明JavaScript時參考了不少awk的設計的原因.不過目前,ES6中已經有了類似於Java等語言的Map類型,鍵可以是任意類型的值.請參考我翻譯的MDN文檔Map

3.另一個技巧
郵件裡還提到了另外一個技巧: 複製代碼 代碼如下:> Array.apply(null, Array(3)).map(Function.prototype.call.bind(Number))
[ 0, 1, 2 ]

這大概等同於下面的寫法 複製代碼 代碼如下:Array.apply(null, Array(3)).map(
function (x,i,...) { return Number.call(x,i,...) })

注意,x是call方法的第一個參數,它作為了Number函數中的this值.這個值沒有什麼意義,相當於被忽略.我更喜歡下面這個能讓人一眼就看明白的寫法: 複製代碼 代碼如下: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)

雖然使用自訂的函數更清晰,但自訂的函數肯定沒有原生方法快.舉個例子:

複製代碼 代碼如下: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方法來trim掉每個數組元素的空格,使用原生的方法雖然難理解.但效率高.看不懂的可以查看下我翻譯的MDN文檔Array.prototype.map()

4.實際用途?

在實際生產中,使用上面講的建立密集數組的方法會讓別人無法讀懂你的代碼.所以封裝成一個工具函數會更好,比如 _.range:

複製代碼 代碼如下:> _.range(3)
[ 0, 1, 2 ]

和map配合使用,可以使用某個指定的值填充整個數組. 複製代碼 代碼如下:> _.range(3).map(function () { return "a" })
[ 'a', 'a', 'a' ]

譯者注:其他語言裡,都有方便的產生遞增數字列表的辦法,比如perl和ruby裡使用1..100,python裡使用range(100),還有一個常見的需求就是產生一個重複某個欄位的字串,在ruby和python裡,可以用"a"*100,在perl裡用"a"x100,在JavaScript中,可以用Array(100).join("a")

5.相關文章

  1. Iterating over arrays and objects in JavaScript(已牆)
  2. Trying out Underscore on Node.js(已牆)
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.