亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

怎樣在JavaScript中創(chuàng)建和填充任意長(zhǎng)度的數(shù)組

ispring / 625人閱讀

摘要:創(chuàng)建數(shù)組構(gòu)造函數(shù)如果要?jiǎng)?chuàng)建具有給定長(zhǎng)度的,常用的方法是使用構(gòu)造函數(shù)這種方法很方便,但是有兩個(gè)缺點(diǎn)即便你稍后再用值把數(shù)組完全填滿,這種空洞也會(huì)使這個(gè)略微變慢。所以操作這個(gè)數(shù)組時(shí)應(yīng)該比用構(gòu)造函數(shù)創(chuàng)建的更快。

翻譯:瘋狂的技術(shù)宅
原文: http://2ality.com/2018/12/cre...

本文首發(fā)微信公眾號(hào):jingchengyideng
歡迎關(guān)注,每天都給你推送新鮮的前端技術(shù)文章

創(chuàng)建數(shù)組的最佳方法是通過字面方式:

const arr = [0,0,0];

不過這并不是長(zhǎng)久之計(jì),比如當(dāng)我們需要?jiǎng)?chuàng)建大型數(shù)組時(shí)。這篇博文探討了在這種情況下應(yīng)該怎么做。

沒有空洞的數(shù)組往往表現(xiàn)得更好

在大多數(shù)編程語(yǔ)言中,數(shù)組是連續(xù)的值序列。在 JavaScript 中,Array 是一個(gè)將索引映射到元素的字典。它可以存在空洞(holes) —— 零和數(shù)組長(zhǎng)度之間的索引沒有映射到元素(“缺失索引”)。例如,下面的 Array 在索引 1 處有一個(gè)空洞:

> Object.keys(["a",, "c"])
[ "0", "2" ]

沒有空洞的數(shù)組也稱為 dense packed。密集數(shù)組往往表現(xiàn)更好,因?yàn)樗鼈兛梢赃B續(xù)存儲(chǔ)(內(nèi)部)。一旦出現(xiàn)了空洞,內(nèi)部表示就必須改變。我們有兩種選擇:

字典。查找時(shí)會(huì)消耗更多時(shí)間,而且存儲(chǔ)開銷更大。

連續(xù)的數(shù)據(jù)結(jié)構(gòu),對(duì)空洞進(jìn)行標(biāo)記。然后檢查對(duì)應(yīng)的值是否是一個(gè)空洞,這也需要額外的時(shí)間。

不管是哪種情況,如果引擎遇到一個(gè)空洞,它不能只返回 undefined,它必須遍歷原型鏈并搜索一個(gè)名稱為“空洞索引”的屬性,這需要花費(fèi)更多時(shí)間。

在某些引擎中,例如V8,如果切換到性能較低的數(shù)據(jù)結(jié)構(gòu),這種改變將會(huì)是永久性的。即使所有空洞都被填補(bǔ),它們也不會(huì)再切換回來了。

關(guān)于 V8 是如何表示數(shù)組的,請(qǐng)參閱Mathias Bynens的文章“V8中的元素類型”。

創(chuàng)建數(shù)組 Array 構(gòu)造函數(shù)

如果要?jiǎng)?chuàng)建具有給定長(zhǎ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), []);

這種方法很方便,但是有兩個(gè)缺點(diǎn):

即便你稍后再用值把數(shù)組完全填滿,這種空洞也會(huì)使這個(gè) Array 略微變慢。

空洞的默認(rèn)值一般不會(huì)是元素的初始“值”。常見的默認(rèn)值是零。

Array 構(gòu)造函數(shù)后面加上 .fill() 方法

.fill()方法會(huì)更改當(dāng)前的 Array 并使用指定的值去填充它。這有助于在用 new Array() 創(chuàng)建數(shù)組后對(duì)其進(jìn)行初始化:

const LEN = 3;
const arr = new Array(LEN).fill(0);
assert.deepEqual(arr, [0, 0, 0]);

警告:如果你用對(duì)象作為參數(shù)去 .fill() 一個(gè)數(shù)組,所有元素都會(huì)引用同一個(gè)實(shí)例(也就是這個(gè)對(duì)象沒有被克隆多份):

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} ]);

稍后我們會(huì)遇到的一種填充方法( Array.from() )則沒有這個(gè)問題。

.push() 方法
const LEN = 3;
const arr = [];
for (let i=0; i < LEN; i++) {
  arr.push(0);
}
assert.deepEqual(arr, [0, 0, 0]);

這一次,我們創(chuàng)建并填充了一個(gè)數(shù)組,同時(shí)里面沒有出現(xiàn)漏洞。所以操作這個(gè)數(shù)組時(shí)應(yīng)該比用構(gòu)造函數(shù)創(chuàng)建的更快。不過 創(chuàng)建 數(shù)組的速度比較慢,因?yàn)橐婵赡苄枰S著數(shù)組的增長(zhǎng)多次重新分配連續(xù)的內(nèi)存。

使用 undefined 填充數(shù)組

Array.from() 將 iterables 和類似數(shù)組的值轉(zhuǎn)換為 Arrays ,它將空洞視為 undefined 元素。這樣可以用它將每個(gè)空洞都轉(zhuǎn)換為 undefined

> Array.from({length: 3})
[ undefined, undefined, undefined ]

參數(shù) {length:3} 是一個(gè)長(zhǎng)度為 3 的類似 Array 的對(duì)象,其中只包含空洞。也可以使用 new Array(3),但這樣一般會(huì)創(chuàng)建更大的對(duì)象。
下面這種方式僅適用于可迭代的值,并且與 Array.from()具有類似的效果:

> [...new Array(3)]
[ undefined, undefined, undefined ]

不過 Array.from()通過 new Array() 創(chuàng)建它的結(jié)果,所以你得到的仍然是一個(gè)稀疏數(shù)組。

使用 Array.from() 進(jìn)行映射

如果提供映射函數(shù)作為其第二個(gè)參數(shù),則可以使用 Array.from() 進(jìn)行映射。

用值填充數(shù)組

使用小整數(shù)創(chuàng)建數(shù)組:

> Array.from({length: 3}, () => 0)
[ 0, 0, 0 ]

使用唯一(非共享的)對(duì)象創(chuàng)建數(shù)組:

> Array.from({length: 3}, () => ({}))
[ {}, {}, {} ]

按照數(shù)值范圍進(jìn)行創(chuàng)建

用升序整數(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()返回一個(gè)可迭代的序列。我們將其展開并轉(zhuǎn)換為數(shù)組。

備忘速查:創(chuàng)建數(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}, () => ({}))
[{}, {}, {}] (唯一對(duì)象)

用整數(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è)重點(diǎn)是可讀性,而不是性能。

你是否需要?jiǎng)?chuàng)建一個(gè)空的數(shù)組,以后將會(huì)完全填充?

new Array(LEN)

你需要?jiǎng)?chuàng)建一個(gè)用原始值初始化的數(shù)組嗎?

new Array(LEN).fill(0)

你需要?jiǎng)?chuàng)建一個(gè)用對(duì)象初始化的數(shù)組嗎?

Array.from({length: LEN}, () => ({}))

你需要?jiǎng)?chuàng)建一系列整數(shù)嗎?

Array.from({length: END-START}, (x, i) => i+START)

如果你正在處理整數(shù)或浮點(diǎn)數(shù)的數(shù)組,請(qǐng)考慮Typed Arrays —— 它就是為這個(gè)目的而設(shè)計(jì)的。它們不能存在空洞,并且總是用零進(jìn)行初始化。

提示:一般來說數(shù)組的性能無關(guān)緊要

對(duì)于大多數(shù)情況,我不會(huì)過分擔(dān)心性能。即使是帶空洞的數(shù)組也很快。使代碼易于理解更有意義。

另外引擎優(yōu)化的方式和位置也會(huì)發(fā)生變化。今天最快的方案可能明天就不是了。

致謝

感謝 Mathias Bynens 和 Benedikt Meurer 幫我了解 V8 的詳細(xì)信息。

擴(kuò)展閱讀

Chapter “Typed Arrays” in “Exploring ES6”

Sect. “ES6 and holes in Arrays” in “Exploring ES6”

歡迎繼續(xù)閱讀本專欄其它高贊文章:

12個(gè)令人驚嘆的CSS實(shí)驗(yàn)項(xiàng)目

世界頂級(jí)公司的前端面試都問些什么

CSS Flexbox 可視化手冊(cè)

過節(jié)很無聊?還是用 JavaScript 寫一個(gè)腦力小游戲吧!

從設(shè)計(jì)者的角度看 React

CSS粘性定位是怎樣工作的

一步步教你用HTML5 SVG實(shí)現(xiàn)動(dòng)畫效果

程序員30歲前月薪達(dá)不到30K,該何去何從

第三方CSS安全嗎?

談?wù)剆uper(props) 的重要性

本文首發(fā)微信公眾號(hào):jingchengyideng 歡迎掃描二維碼關(guān)注公眾號(hào),每天都給你推送新鮮的前端技術(shù)文章

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/102067.html

相關(guān)文章

  • 回到基礎(chǔ):如何用原生 DOM API 生成表格

    摘要:接下來該填表了生成行和單元格為了填充表格可以遵循同樣的方法,但這次我們需要迭代數(shù)組中的每個(gè)對(duì)象。對(duì)于每個(gè)對(duì)象,我們可以使用生成單元格。 翻譯:瘋狂的技術(shù)宅原文:https://www.valentinog.com/bl... 本文首發(fā)微信公眾號(hào):jingchengyideng歡迎關(guān)注,每天都給你推送新鮮的前端技術(shù)文章 怎樣用原生 JavaScript 生成表格需?本文告訴你答案!...

    Sunxb 評(píng)論0 收藏0
  • JavaScript數(shù)組

    摘要:與稀疏數(shù)組對(duì)立的為密集數(shù)組,密集數(shù)組的索引會(huì)被持續(xù)的創(chuàng)建,并且其元素的數(shù)量等于其長(zhǎng)度。創(chuàng)建一個(gè)長(zhǎng)度為的數(shù)組,并初始化了個(gè)元素使用構(gòu)造函數(shù)創(chuàng)建數(shù)組對(duì)象的時(shí)候,關(guān)鍵字是可以省略的。另外使用和刪除元素是影響數(shù)組的長(zhǎng)度的。 說明:本文只總結(jié)了JavaScript數(shù)組在web端的行為,不包括NodeJs端的行為。本文不涉及類型化數(shù)組(TypedArray)的討論、總結(jié)。 一、什么是數(shù)組 數(shù)組的定...

    HtmlCssJs 評(píng)論0 收藏0
  • JavaScript V8 中元素種類及性能優(yōu)化

    摘要:常規(guī)元素,不能表示為或雙精度的值。元素種類可從過渡轉(zhuǎn)變?yōu)?。這是一個(gè)簡(jiǎn)化的可視化,僅顯示最常見的元素種類只能通過格子向下過渡。目前有種不同的元素種類,每種元素都有自己的一組可能的優(yōu)化。再次重申更具體的元素種類可以進(jìn)行更細(xì)粒度的優(yōu)化。 原文:Elements kinds in V8 JavaScript 對(duì)象可以具有與它們相關(guān)聯(lián)的任意屬性。對(duì)象屬性的名稱可以包含任何字符。JavaScrip...

    UsherChen 評(píng)論0 收藏0
  • JS 預(yù)分配數(shù)組長(zhǎng)度,到底是變慢還是變快?

    摘要:可以更有效地處理密集數(shù)組。然后有人提出了一個(gè)疑問為什么先指定長(zhǎng)度再初始化測(cè)試出來會(huì)快一點(diǎn)其實(shí),兩者相比只是可能變慢。具體因素有很多,比如預(yù)分配一個(gè)很大的數(shù)組,這時(shí)可以變快,的函數(shù)就是這么做的。如果數(shù)組很大,預(yù)先分配大小后性能反而會(huì)提升。 在我的上一篇文章 JavaScript 在 V8 中的元素種類及性能優(yōu)化 中寫道: showImg(https://segmentfault.com...

    zxhaaa 評(píng)論0 收藏0
  • JavaScript引用類型---Array

    摘要:默認(rèn)為如果大于等于數(shù)組長(zhǎng)度,則返回該數(shù)組不會(huì)被搜索返回值一個(gè)類型方法返回在數(shù)組中可以找到一個(gè)給定元素的第一個(gè)索引,如果不存在,則返回。 一、創(chuàng)建Array對(duì)象實(shí)例 let array1 = [1,2,3,4]; //構(gòu)造函數(shù) let array2 = new Array(1,2,3,4); //[1,2,3,4] let array3 = new Arr...

    macg0406 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<