稀疏數組
概念
在一些後端語言中,如 C,數組內的值一般被分配在一系列連續的內存地址上,可是在 js 中,某些數組內存則不是連續的,所謂稀疏,顧名思義,不連續,存在一些空隙;web
例如:後端
var arr = new Array(3);console.log(arr);// (3) [empty × 3]
數組
微信
app
經過以上方法建立數組,其中 Array(3)
中的參數 3 表示數組的長度,這個數組就是稀疏的,控制檯輸出通常帶有 empty
字樣,或者像下面這樣建立數組:性能
var arr = [1,,2];console.log(arr);// (3) [1, empty, 2]
flex
url
spa
由於定義語句中兩個逗號之間無字符,沒有定義值,一樣帶有 empty
字樣,表明稀疏數組,這裏能夠把 empty
理解爲上面講到的 空隙;.net
特色
接下來看一下稀疏數組特殊在什麼地方,舉個例子說明:
var arr1 = [1, 2, 3]; // 正常數組var arr2 = new Array(3); // 稀疏數組var arr3 = [1, , 3]; // 稀疏數組console.log(arr1.length, arr2.length, arr3.length);// 3 3 3console.log(arr2[0], arr3[1]);// undefined undefinedfor (var i = 0; i < 3; i++) { console.log(arr1[i], arr2[i], arr3[i]);}// 1 undefined 1// 2 undefined undefined// 3 undefined 3arr1.forEach(function(x){ console.log(x);});// 1// 2// 3arr2.forEach(function(x){ console.log(x);});// (無輸出)arr3.forEach(function(x){ console.log(x);});// 1// 3console.log(0 in arr3, 1 in arr3);// true false
總結一下,建立的稀疏數組,其長度(length)與定義長度值一致;空隙 值能夠被單獨訪問到,而且不是以前出現的 empty
字樣,而是 undefined
,好比例子中出現 undefined
時都是使用 arr[i]
這樣的索引直接訪問方式;使用某些數組方法如 forEach()
時,會忽略掉空隙值,只處理正常值,因此也會使得 1inarr3
值爲 false
,即數組中不存在該索引;
細想一下,js 這樣處理的緣由多半是去除沒必要要的性能開銷,當數組至關大時,能夠避免處理一些未初始化的值,但這樣也同時使得開發中會出現一些問題,因此應儘可能避免;
舉個例子來查看一下性能如何:
console.time('one');// 密集數組Array(...Array(1e5)).forEach(function(){ ;});console.timeEnd('one');console.time('two');// 稀疏數組Array(1e5).forEach(function(){ ;});console.timeEnd('two');// one: 26.3759765625ms// two: 5.701171875ms
能夠看出在處理較大數組時,稀疏數組確實能下降很多性能開銷;
密集數組
概念
與稀疏相對應,則存在密集,定義也就是元素中不存在 空隙 值,其實密集數組基本就是平時常見的正常數組;
例如:
var arr1 = [1, 2, 3];var arr2 = new Array(1, 2, 3);arr2.forEach(function(x){ console.log(x);});// 1// 2// 3
以上都是一些定義密集數組的方法,而且數組中的值都能被正常訪問或遍歷處理;
區別
運用時須要注意如下狀況:
var arr1 = [undefined, undefined, undefined];var arr2 = new Array(3);console.log(arr1[0], arr2[0]);// undefined undefinedarr1.forEach(function(x){ console.log(x);})// undefined// undefined// undefinedarr2.forEach(function(x){ console.log(x);})// (無輸出)
即顯式的聲明值爲 undefined
並不表明這個值就是以前提到的空隙值,雖然兩者經過索引訪問時的值都返回 undefined
,可是其根本仍是有區別的,顯式聲明過的是能夠被遍歷等操做訪問的,不會被當成空隙值被忽略;
拓展
一般在不少狀況下,咱們想要直接聲明一個數組並賦予其一些特定的初始值,而且爲了不問題,一般是但願申明爲密集數組的,下面就介紹一些經常使用的方法或技巧:
var arr1 = new Array(3).fill(1);console.log(arr1);// [1, 1, 1]var arr2 = Array.fill().map((x, i) => i);console.log(arr2);// [0, 1, 2]var arr3 = Array.apply(null, Array(3));console.log(arr3);// [undefined, undefined, undefined]// 這樣聲明的是密集數組,不是稀疏的var arr4 = new Array(4).join('a').split('');console.log(arr4);// ['a', 'a', 'a']// 注意定義數組長度比輸出數組大 1
其它更多的方法能夠自行類推;
本文分享自微信公衆號 - 程序騎士(program-knight)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。