JavaScript中的數組創建

JavaScript中的數組創建

本文轉載自:眾成翻譯
譯者:loveky
鏈接:http://www.zcfy.cc/article/713
原文:http://rainsoft.io/power-up-the-array-creation-in-javascript/

數組是一個包含了對象或原始類型的有序集合。很難想象一個不使用數組的程序會是什么樣。

以下是幾種操作數組的方式:

  1. 初始化數組并設置初始值

  2. 通過索引訪問數組元素

  3. 添加新元素

  4. 刪除現有元素

本文涵蓋了數組的初始化以及設置初始值的操作。在JavaScript中要做到這一點的基本方法是使用數組字面量,例如[1, 5, 8]或是數組構造器new Array (1, 5, 8)

除了手動枚舉之外,JavaScript還提供了更有趣更直接的數組創建方式。讓我一起看看在JavaScript中初始化數組的一般場景和高級場景吧。

1. 數組字面量

數組字面量由一組包裹在方括號[ ]之間的逗號分隔的元素element1, element2, ..., elementN組成。

讓我們看幾個數組字面量的例子:

在JS Bin中查看

let numbers = [1, 5, 7, 8];
let planets = ['Earth', 'Mercury', 'Jupiter'];

數組字面量可以包含任意類型的元素,包括null, undefined, 原始類型以及對象:

在JS Bin中查看

let mixed = [1, 'Earth', null, NaN, undefined, ['Mars']];

1.1 數組字面量中的逗號

逗號,用來分隔數組字面量中的元素。基于逗號的位置或是逗號之間元素的缺失的情況,不同結構的數組會被創建。

讓我們詳細看一看現有的三種情況。

第一種情況:普通的數組字面量

通常情況是在任何一對逗號之間都有一個元素并且數組字面量不以逗號開始或結尾。這是推薦的使用逗號分隔手動初始化數組的方式:

在JS Bin中查看

let items = ['first', 'second', 'third'];
items; // => ['first', 'second', 'third']

items是由2個逗號分隔的3個元素創建的。

在這個例子中item是一個密集數組,因為它的元素有著連續的索引(或者簡單來說數組中沒有空洞)。

大多數時候,你會使用這種方式初始化數組。

第二種情況: 在數組末尾的一個無用逗號

第二種情況和第一種情況類似,只不過在最后一個逗號之后沒有指定元素。這種情況中,最后一個逗號會被JavaScript忽略:

在JS Bin中查看

let items = ['first', 'second', 'third', ];
items; // => ['first', 'second', 'third']

在元素'third'之后指定的一個逗號,它是數組中的最后一個逗號并且在那之后沒有任何元素。這個末尾的逗號是無用的,意味著它對新創建的數組沒有任何影響。

這種情況下JavaScript也會創建一個密集數組。

第三種情況: 逗號之間沒有元素

第三種情況發生在當一對逗號之間沒有指定元素或是數組字面量以一個逗號開始時。

這會創建一個稀疏數組:一個其元素索引不連續的集合(換句話說數組中存在空洞)。

下面的數組字面量以逗號開始,創建了一個稀疏數組:

在JS Bin中查看

let items = [, 'first', 'second', 'third'];
items;        // => [<1 empty slot>, 'first', 'second', 'third']
items[0];     // => undefined
items[1];     // => 'first'
items.length; // => 4

數組字面量[, ...]以逗號開始。結果是items是一個稀疏數組,在索引0的位置是一個空slot。訪問空slot items[0]會得到undefined

區分一個空slot和一個值是undefined的元素是很重要的。通過索引訪問這種類型的元素時都會得到undefined,這使得區分它們變得很棘手。

空slot意味著數組在某個索引位置上沒有元素(index in array返回false),這與一個值是undefined的元素(index in array返回true)是不同的。

需要注意的是空slot在Firefox的控制臺會被顯示為<1 empty slot>,這是展示空slot的正確方法。Chrome的控制臺會展示undefined x 1。其它瀏覽器的控制臺只會簡單的展示undefined

當數組字面量的兩個逗號之間沒有元素時也會創建一個稀疏數組:

在JS Bin中查看

let items = ['first', , 'second', 'third'];
items;        // => ['first', <1 empty slot> ,'second', 'third']
items[0];     // => 'first'
items[1];     // => undefined
items.length; // => 4

數組字面量包含了中間沒有元素的逗號:[... , , ...]。這樣item成了一個索引1處是一個空slot的稀疏數組。訪問空slot items[1]會得到undefined

通常你應該避免這種會創建稀疏數組的使用方式。同時你也應該盡可能的不去操作稀疏數組。

在一個數組字面量中刪除或是添加元素時你可能會在不經意間創建一個稀疏數組。因此在修改之后切記仔細檢查。

1.2 spread運算符帶來的改善

ECMAScript 6中引入的spread運算符改善了使用其它數組中的元素初始新數組這一操作。

在很多場景下spread運算符都可以使數組創建變得更簡單。方法就是在數組字面量中把...作為源數組的前綴,然后源數組中的元素就被包括到新創建的數組中了。就這么簡單。

下面的數組字面量在創建時使用了spread運算符:

在JS Bin中查看

let source = ['second', 'third'];
let items = ['first', ...source];
items; // => ['first', 'second', 'third']

數組字面量['First', ...source]表示'First'會被作為數組中的第一個元素。剩余的元素則是通過spread運算符從source數組取得。

常規的元素枚舉方式可以和spread運算符可以不受限制的組合在一起。

在JS Bin中查看

let odds = [1, 3, 5];
let evens = [4, 6];
let zero = 0;
let negative = -1;
let items = [...odds, zero, ...evens, negative];
items; // => [1, 3, 5, 0, 4, 6, -1]

創建items時使用一個組合了普通變量zeronegative以及前置spread運算符的源數組...odds...evens的集合。

由于spread運算符接收的是普通的可迭代對象(數組默認就是可迭代的),這使得自定義的初始化成為可能。

一個生成器函數也會返回一個可迭代的生成器對象,因此你可以利用生成器的靈活性來創建數組。

讓我們創建一個第一個參數代表元素值第二個參數代表元素數量的生成器函數。然后使用它和spread運算符以及數組字面量來初始化新數組:

在JS Bin中查看

function* elements(element, length) {let index = 0;while (length > index++) {yield element;}
}
[...elements(0, 5)];    // => [0, 0, 0, 0, 0]
[...elements('hi', 2)]; // => ['hi', 'hi']

每次執行elements(element, length)時都會創建一個生成器對象。spread運算符會利用該生成器對象來初始化數組。

[...elements(0, 5)]會創建一個有5個0的數組。而[...elements('hi', 2)]會創建一個有兩個字符串'h1'的數組。

2. 數組構造器

JavaScript中的數組是一個對象。和任何對象一樣,它有一個可以用來創建新實例的構造器函數Array。讓我們看一個例子:

在JS Bin中查看

// 構造器調用
let arrayConstr = new Array(1, 5);
arrayConstr;                        // => [1, 5]
typeof arrayConstr;                 // => 'object'
arrayConstr.constructor === Array;  // => true
// 數組字面量
let arrayLiteral = [1, 5];
arrayLiteral;                       // => [1, 5]
typeof arrayLiteral;                // => 'object'
arrayLiteral.constructor === Array; // => true

arrayConstrarrayLiteral都是數組實例,它們的構造器都是Array。對象arrayConstr是通過構造器調用創建的:new Array(1, 5)

你也可以像調用普通函數那樣通過Array來創建數組實例:Array(1, 5)

你應該更傾向于使用字面量[item1, item2, ..., itemN]而不是構造器new Array(item1, item2, ..., itemN)來創建數組。主要原因是數組字面量的寫法更短,更簡單。還有一個原因就是數組構造器在第一個參數是不同類型的值時,產生的怪異行為。

讓我們看看Array使如何根據第一個參數的類型以及參數的個數來創建數組實例的吧。

2.1 數值類型的參數下創建稀疏數組

當數組構造器new Array(numberArg)以一個單一的數值類型的參數調用時,JavaScript會創建一個帶有參數指定的個數的空slot的稀疏數組。

看一個例子:

在JS Bin中查看

let items = new Array(3);
items;        // => [<3 empty slots>]
items.length; // => 3

new Array(3)是一個帶有單一參數3的構造器調用。一個長度為3的稀疏數組items被創建了,但實際上它并不包含任何元素而只是有幾個空slot。

這種創建數組的方式本身并沒有什么價值。然而把它和一些靜態方法組合起來用于創建指定長度的數組并填充生成的元素時卻是有用的。

2.2 枚舉元素

如果調用Array構造器時傳入了一個參數列表而不是單個數字,那么這些參數就會成為數組的元素。

這種方式和數組字面量的方式幾乎一樣,只不過是在一個構造器調用中而已。

下面的例子創建了一個數組:

let items = new Array('first', 'second', 'third');
items; // => ['first', 'second', 'third']

new Array('first', 'second', 'third')使用參數中的元素創建了一個數組。

由于spread運算符的靈活性,在構造器調用中使用來自其它數組的元素也是可行的:

在JS Bin中查看

let source = new Array('second', 'third');
let items = new Array('first', ...source);
items; // => ['first', 'second', 'third']

new Array('First', ...source)創建數組時使用了'First'元素以及source數組中的所有元素。

無論哪種方式,你都應該傾向于使用數組字面量,因為它更簡單直接。

2.3 有用的靜態方法

當讀到關于通過在構造器調用中傳入一個數字來創建稀疏數組的部分時你可能好奇這有什么實際的用處。

ECMAScript 6增加了一些有用的方法如Array.prototype.fill()Array.from()。這兩個方法都可以用來填充一個稀疏數組中的空slot。

讓我使用fill()方法來創建一個包含5個0的數組:

在JS Bin中查看

let zeros = new Array(5).fill(0);
zeros; // => [0, 0, 0, 0, 0]

new Array(5)創建了一個有5個空slot的稀疏數組。接著fill(0)方法用0填充了空slot。

靜態方法Array.from()則有著更寬的使用場景。像上邊的例子一樣,讓我們創建一個包含5個0的數組:

在JS Bin中查看

let zeros = Array.from(new Array(5), () => 0);
zeros; // => [0, 0, 0, 0, 0]

一個通過new Array(5)創建的長度為5的稀疏組數作為參數被傳遞給Array.from()。第二個參數作為一個返回0的映射函數。

共執行了5次迭代,每次迭代中箭頭函數的返回值被用作數組的元素。

由于在每次迭代中都會執行映射函數,因此動態創建數組元素是可行的。讓我們創建一個包含15的數組:

在JS Bin中查看

let items = Array.from(new Array(5), (item, index) => index + 1);
items; // => [1, 2, 3, 4, 5]

映射函數被調用時會傳入兩個參數:當前的item以及當前迭代的index。索引參數被用來生成元素:index + 1

Array.from()的第一個參數可以接受任何可迭代對象,這使得它更有價值。

讓我們使用一個生成器對象創建一個遞增的數字列表:

在JS Bin中查看

function* generate(max) {let count = 0;while (max > count++) {yield count;}
}
let items = Array.from(generate(5));
items;       // => [1, 2, 3, 4, 5]
let itemsSpread = [...generate(5)];
itemsSpread; // => [1, 2, 3, 4, 5]

generate(max)是一個生成器函數,它會生成從一串從1max的數字。

Array.from(generate(5))使用一個生成器對象作為參數創建了一個包含15數字的數組。

使用spread運算符[...generate(5)]和數組字面量可以達到同樣的目的。

3. 總結

數組初始化是操作集合時的常見操作。JavaScript提供了多種方法以及靈活性來實現該目的。

數組構造器的行為在很多情況下會讓你感到意外。因此數組字面量是初始化數組實例更好,更簡單的方式。

當數組需要根據基于每個迭代元素的計算進行初始化時,Array.from()是一個不錯的選擇。

如果數組元素需要被填充為同一個值,使用Array.prototype.fill()new Array(length)的組合。

不要低估可迭代對象和生成器函數的能力,它們可以和spread運算符組合起來使用在數組字面量或是Array.from()中。

轉載于:https://www.cnblogs.com/wwhhq/p/8079102.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/391743.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/391743.shtml
英文地址,請注明出處:http://en.pswp.cn/news/391743.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

CODEVS——T1519 過路費

http://codevs.cn/problem/1519/ 時間限制: 1 s空間限制: 256000 KB題目等級 : 大師 Master題解查看運行結果題目描述 Description在某個遙遠的國家里,有 n個城市。編號為 1,2,3,…,n。這個國家的政府修建了m 條雙向道路,每條道路連接著兩個城市。政府規…

pca數學推導_PCA背后的統計和數學概念

pca數學推導As I promised in the previous article, Principal Component Analysis (PCA) with Scikit-learn, today, I’ll discuss the mathematics behind the principal component analysis by manually executing the algorithm using the powerful numpy and pandas lib…

pandas之cut

cut( )用來把一組數據分割成離散的區間。 cut(x, bins, rightTrue, labelsNone, retbinsFalse, precision3, include_lowestFalse, duplicatesraise) # x:被切分的數據,必須是一維的 # bins:①int型整數:將x按照數值大小平均分成分…

為Tueri.io構建React圖像優化組件

Let’s face it, image optimization is hard. We want to make it effortless.面對現實吧,圖像優化非常困難。 我們希望毫不費力。 When we set out to build our React Component there were a few problems we wanted to solve:當我們開始構建React組件時&#…

紅黑樹分析

紅黑樹的性質: 性質1:每個節點要么是黑色,要么是紅色。 性質2:根節點是黑色。性質3:每個葉子節點(NIL)是黑色。性質4:每個紅色節點的兩個子節點一定都是黑色。不能有兩個紅色節點相…

overlay 如何實現跨主機通信?- 每天5分鐘玩轉 Docker 容器技術(52)

上一節我們在 host1 中運行了容器 bbox1,今天將詳細討論 overlay 網絡跨主機通信的原理。 在 host2 中運行容器 bbox2: bbox2 IP 為 10.0.0.3,可以直接 ping bbox1: 可見 overlay 網絡中的容器可以直接通信,同時 docke…

第 132 章 Example

這里介紹一個負載均衡放置問題,我們可以把它擺放在任何位置,每種方案都各有優缺點,需要根據你的實際情況選擇使用 適用于HAProxy / Nginx / LVS 等等 這里用web,db為例子,講述負載均衡之間的關系 132.1. 雙負載均衡的用法 User --…

Python:實現圖片裁剪的兩種方式——Pillow和OpenCV

原文:https://blog.csdn.net/hfutdog/article/details/82351549 在這篇文章里我們聊一下Python實現圖片裁剪的兩種方式,一種利用了Pillow,還有一種利用了OpenCV。兩種方式都需要簡單的幾行代碼,這可能也就是現在Python那么流行的原…

第一個應在JavaScript數組的最后

by Thomas Barrasso由Thomas Barrasso 第一個應在JavaScript數組的最后 (The first shall be last with JavaScript arrays) So the last shall be [0], and the first [length — 1].所以最后一個應該是[0] ,第一個[length_1]。 – Adapted from Matthew 20:16–根…

鼠標移動到ul圖片會擺動_我們可以從擺動時序分析中學到的三件事

鼠標移動到ul圖片會擺動An opportunity for a new kind of analysis of Major League Baseball data may be upon us soon. Here’s how we can prepare.不久之后,我們將有機會對美國職棒大聯盟數據進行新的分析。 這是我們準備的方法。 It is tempting to think t…

leetcode 1052. 愛生氣的書店老板(滑動窗口)

今天,書店老板有一家店打算試營業 customers.length 分鐘。每分鐘都有一些顧客(customers[i])會進入書店,所有這些顧客都會在那一分鐘結束后離開。 在某些時候,書店老板會生氣。 如果書店老板在第 i 分鐘生氣&#xf…

回到網易后開源APM技術選型與實戰

篇幅一:APM基礎篇\\1、什么是APM?\\APM,全稱:Application Performance Management ,目前市面的系統基本都是參考Google的Dapper(大規模分布式系統的跟蹤系統)來做的,翻譯傳送門《google的Dappe…

持續集成持續部署持續交付_如何開始進行持續集成

持續集成持續部署持續交付Everything you need to know to get started with continuous integration: branching strategies, tests automation, tools and best practices.開始進行持續集成所需的一切:分支策略,測試自動化,工具和最佳實踐。…

51nod 1073約瑟夫環

思路傳送門 &#xff1a;http://blog.csdn.net/kk303/article/details/9629329 n里面挑選m個 可以遞推從n-1里面挑m個 然后n-1里面的x 可以轉換成 n里面的x 的公式 x &#xff08;xm&#xff09;%n; #include <bits/stdc.h> using namespace std;int main () {int n,m;s…

如何選擇優化算法遺傳算法_用遺傳算法優化垃圾收集策略

如何選擇優化算法遺傳算法Genetic Algorithms are a family of optimisation techniques that loosely resemble evolutionary processes in nature. It may be a crude analogy, but if you squint your eyes, Darwin’s Natural Selection does roughly resemble an optimisa…

robot:截圖關鍵字

參考&#xff1a; https://www.cnblogs.com/hong-fithing/p/9656221.html--python https://blog.csdn.net/weixin_43156282/article/details/87350309--robot https://blog.csdn.net/xiongzaiabc/article/details/82912280--截圖指定區域 轉載于:https://www.cnblogs.com/gcgc/…

leetcode 832. 翻轉圖像

給定一個二進制矩陣 A&#xff0c;我們想先水平翻轉圖像&#xff0c;然后反轉圖像并返回結果。 水平翻轉圖片就是將圖片的每一行都進行翻轉&#xff0c;即逆序。例如&#xff0c;水平翻轉 [1, 1, 0] 的結果是 [0, 1, 1]。 反轉圖片的意思是圖片中的 0 全部被 1 替換&#xff…

SVN服務備份操作步驟

SVN服務備份操作步驟1、準備源服務器和目標服務器源服務器&#xff1a;192.168.1.250目標服務器&#xff1a;192.168.1.251 root/rootroot 2、對目標服務器&#xff08;251&#xff09;裝SVN服務器&#xff0c; 腳本如下&#xff1a;yum install subversion 3、創建一個新的倉庫…

SpringCloud入門(一)

1. 系統架構演變概述 #mermaid-svg-F8dvnEDl6rEgSP97 .label{font-family:trebuchet ms, verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-F8dvnEDl6rEgSP97 .label text{fill:#333}#mermaid-svg-F8dvnEDl6rEgSP97 .node rect,#merm…

PullToRefreshListView中嵌套ViewPager滑動沖突的解決

PullToRefreshListView中嵌套ViewPager滑動沖突的解決 最近恰好遇到PullToRefreshListView中需要嵌套ViewPager的情況,ViewPager 作為頭部添加到ListView中&#xff0c;發先ViewPager在滑動過程中流暢性太差幾乎很難左右滑動。在網上也看了很多大神的介紹&#xff0c;看了ViewP…