国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

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

ispring / 574人閱讀

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

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

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

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

const arr = [0,0,0];

不過這并不是長久之計,比如當我們需要創(chuàng)建大型數(shù)組時。這篇博文探討了在這種情況下應該怎么做。

沒有空洞的數(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ù)結構,對空洞進行標記。然后檢查對應的值是否是一個空洞,這也需要額外的時間。

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

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

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

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

如果要創(chuàng)建具有給定長度的 Array,常用的方法是使用 Array 構造函數(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 略微變慢。

空洞的默認值一般不會是元素的初始“值”。常見的默認值是零。

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

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

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ù)組時應該比用構造函數(shù)創(chuàng)建的更快。不過 創(chuàng)建 數(shù)組的速度比較慢,因為引擎可能需要隨著數(shù)組的增長多次重新分配連續(xù)的內(nèi)存。

使用 undefined 填充數(shù)組

Array.from() 將 iterables 和類似數(shù)組的值轉換為 Arrays ,它將空洞視為 undefined 元素。這樣可以用它將每個空洞都轉換為 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)建它的結果,所以你得到的仍然是一個稀疏數(shù)組。

使用 Array.from() 進行映射

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

用值填充數(shù)組

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

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

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

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

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

用升序整數(shù)數(shù)列創(chuàng)建數(shù)組:

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

用任意范圍的整數(shù)進行創(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()返回一個可迭代的序列。我們將其展開并轉換為數(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}, () => ({}))
[{}, {}, {}] (唯一對象)

用整數(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]

推薦的模式

我更喜歡下面的方法。我的側重點是可讀性,而不是性能。

你是否需要創(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ù)組的性能無關緊要

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

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

致謝

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

擴展閱讀

Chapter “Typed Arrays” in “Exploring ES6”

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

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

12個令人驚嘆的CSS實驗項目

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

CSS Flexbox 可視化手冊

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

從設計者的角度看 React

CSS粘性定位是怎樣工作的

一步步教你用HTML5 SVG實現(xiàn)動畫效果

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

第三方CSS安全嗎?

談談super(props) 的重要性

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

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

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/102067.html

相關文章

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

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

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

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

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

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

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

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

    zxhaaa 評論0 收藏0
  • JavaScript引用類型---Array

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

    macg0406 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<