您好,登錄后才能下訂單哦!
這篇文章主要介紹了JavaScript中怎么創(chuàng)建和填充任意長度的數(shù)組,具有一定借鑒價值,需要的朋友可以參考下。希望大家閱讀完這篇文章后大有收獲。下面讓小編帶著大家一起了解一下。
創(chuàng)建數(shù)組的最佳方法是通過字面方式:
const arr = [0,0,0];
不過這并不是長久之計,比如當(dāng)我們需要創(chuàng)建大型數(shù)組時。這篇博文探討了在這種情況下應(yīng)該怎么做。
沒有空洞的數(shù)組往往表現(xiàn)得更好
在大多數(shù)編程語言中,數(shù)組是連續(xù)的值序列。在 JavaScript 中,Array 是一個將索引映射到元素的字典。它可以存在空洞(holes) —— 零和數(shù)組長度之間的索引沒有映射到元素(“缺失索引”)。例如,下面的 Array 在索引 1 處有一個空洞:
> Object.keys(['a',, 'c']) [ '0', '2' ]
沒有空洞的數(shù)組也稱為 dense 或 packed。密集數(shù)組往往表現(xiàn)更好,因為它們可以連續(xù)存儲(內(nèi)部)。一旦出現(xiàn)了空洞,內(nèi)部表示就必須改變。我們有兩種選擇:
字典。查找時會消耗更多時間,而且存儲開銷更大。
連續(xù)的數(shù)據(jù)結(jié)構(gòu),對空洞進(jìn)行標(biāo)記。然后檢查對應(yīng)的值是否是一個空洞,這也需要額外的時間。
不管是哪種情況,如果引擎遇到一個空洞,它不能只返回 undefined
,它必須遍歷原型鏈并搜索一個名稱為“空洞索引”的屬性,這需要花費更多時間。
在某些引擎中,例如V8,如果切換到性能較低的數(shù)據(jù)結(jié)構(gòu),這種改變將會是永久性的。即使所有空洞都被填補(bǔ),它們也不會再切換回來了。
關(guān)于 V8 是如何表示數(shù)組的,請參閱Mathias Bynens的文章“V8中的元素類型”。
Array
構(gòu)造函數(shù)如果要創(chuàng)建具有給定長度的 Array,常用的方法是使用 Array
構(gòu)造函數(shù) :
const LEN = 3; const arr = new Array(LEN); assert.equal(arr.length, LEN); // arr only has holes in it assert.deepEqual(Object.keys(arr), []);
這種方法很方便,但是有兩個缺點:
即便你稍后再用值把數(shù)組完全填滿,這種空洞也會使這個 Array 略微變慢。
空洞的默認(rèn)值一般不會是元素的初始“值”。常見的默認(rèn)值是零。
Array
構(gòu)造函數(shù)后面加上 .fill()
方法.fill()
方法會更改當(dāng)前的 Array 并使用指定的值去填充它。這有助于在用 new Array()
創(chuàng)建數(shù)組后對其進(jìn)行初始化:
const LEN = 3; const arr = new Array(LEN).fill(0); assert.deepEqual(arr, [0, 0, 0]);
警告:如果你用對象作為參數(shù)去 .fill()
一個數(shù)組,所有元素都會引用同一個實例(也就是這個對象沒有被克隆多份):
const LEN = 3; const obj = {}; const arr = new Array(LEN).fill(obj); assert.deepEqual(arr, [{}, {}, {}]); obj.prop = true; assert.deepEqual(arr, [ {prop:true}, {prop:true}, {prop:true} ]);
稍后我們會遇到的一種填充方法( Array.from()
)則沒有這個問題。
.push()
方法const LEN = 3; const arr = []; for (let i=0; i < LEN; i++) { arr.push(0); } assert.deepEqual(arr, [0, 0, 0]);
這一次,我們創(chuàng)建并填充了一個數(shù)組,同時里面沒有出現(xiàn)漏洞。所以操作這個數(shù)組時應(yīng)該比用構(gòu)造函數(shù)創(chuàng)建的更快。不過 創(chuàng)建 數(shù)組的速度比較慢,因為引擎可能需要隨著數(shù)組的增長多次重新分配連續(xù)的內(nèi)存。
undefined
填充數(shù)組Array.from()
將 iterables 和類似數(shù)組的值轉(zhuǎn)換為 Arrays ,它將空洞視為 undefined
元素。這樣可以用它將每個空洞都轉(zhuǎn)換為 undefined
:
> Array.from({length: 3}) [ undefined, undefined, undefined ]
參數(shù) {length:3}
是一個長度為 3 的類似 Array 的對象,其中只包含空洞。也可以使用 new Array(3)
,但這樣一般會創(chuàng)建更大的對象。
下面這種方式僅適用于可迭代的值,并且與 Array.from()
具有類似的效果:
> [...new Array(3)] [ undefined, undefined, undefined ]
不過 Array.from()
通過 new Array()
創(chuàng)建它的結(jié)果,所以你得到的仍然是一個稀疏數(shù)組。
Array.from()
進(jìn)行映射如果提供映射函數(shù)作為其第二個參數(shù),則可以使用 Array.from()
進(jìn)行映射。
使用小整數(shù)創(chuàng)建數(shù)組:
> Array.from({length: 3}, () => 0) [ 0, 0, 0 ]
使用唯一(非共享的)對象創(chuàng)建數(shù)組:
> Array.from({length: 3}, () => ({})) [ {}, {}, {} ]
用升序整數(shù)數(shù)列創(chuàng)建數(shù)組:
> Array.from({length: 3}, (x, i) => i) [ 0, 1, 2 ]
用任意范圍的整數(shù)進(jìn)行創(chuàng)建:
> const START=2, END=5; > Array.from({length: END-START}, (x, i) => i+START) [ 2, 3, 4 ]
另一種創(chuàng)建升序整數(shù)數(shù)組的方法是用 .keys()
,它也將空洞看作是 undefined
元素:
> [...new Array(3).keys()] [ 0, 1, 2 ]
.keys()
返回一個可迭代的序列。我們將其展開并轉(zhuǎn)換為數(shù)組。
用空洞或 undefined
填充:
new Array(3)
→ [ , , ,]
Array.from({length: 2})
→ [undefined, undefined]
[...new Array(2)]
→ [undefined, undefined]
填充任意值:
const a=[]; for (let i=0; i<3; i++) a.push(0);
→ [0, 0, 0]
new Array(3).fill(0)
→ [0, 0, 0]
Array.from({length: 3}, () => ({}))
→ [{}, {}, {}]
(唯一對象)
用整數(shù)范圍填充:
Array.from({length: 3}, (x, i) => i)
→ [0, 1, 2]
const START=2, END=5; Array.from({length: END-START}, (x, i) => i+START)
→ [2, 3, 4]
[...new Array(3).keys()]
→ [0, 1, 2]
我更喜歡下面的方法。我的側(cè)重點是可讀性,而不是性能。
你是否需要創(chuàng)建一個空的數(shù)組,以后將會完全填充?
new Array(LEN)
你需要創(chuàng)建一個用原始值初始化的數(shù)組嗎?
new Array(LEN).fill(0)
你需要創(chuàng)建一個用對象初始化的數(shù)組嗎?
Array.from({length: LEN}, () => ({}))
你需要創(chuàng)建一系列整數(shù)嗎?
Array.from({length: END-START}, (x, i) => i+START)
如果你正在處理整數(shù)或浮點數(shù)的數(shù)組,請考慮Typed Arrays —— 它就是為這個目的而設(shè)計的。它們不能存在空洞,并且總是用零進(jìn)行初始化。
對于大多數(shù)情況,我不會過分擔(dān)心性能。即使是帶空洞的數(shù)組也很快。使代碼易于理解更有意義。
另外引擎優(yōu)化的方式和位置也會發(fā)生變化。今天最快的方案可能明天就不是了。
感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享JavaScript中怎么創(chuàng)建和填充任意長度的數(shù)組內(nèi)容對大家有幫助,同時也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,遇到問題就找億速云,詳細(xì)的解決方法等著你來學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。