คอลเล็กชันที่จัดทำดัชนี

คอลเล็กชันที่จัดทำดัชนีคือโครงสร้างข้อมูลที่องค์ประกอบจะได้รับการจัดเก็บและเข้าถึงโดยใช้ดัชนีที่เรียงลำดับเลข ค่าที่จัดเก็บไว้ในคอลเล็กชันที่จัดทำดัชนีจะมีการกำหนดดัชนีตามลำดับตัวเลขโดยเริ่มจาก 0 ซึ่งเป็นรูปแบบที่เรียกว่า "การจัดทำดัชนีเป็นศูนย์" จากนั้นคุณจะเข้าถึงค่าที่จัดเก็บไว้ในคอลเล็กชันที่จัดทำดัชนีได้โดยอ้างอิงดัชนีค่าเหล่านั้น

อาร์เรย์

อาร์เรย์คือคอนเทนเนอร์ที่อาจมีค่าประเภทข้อมูลใดก็ได้เป็น 0 ขึ้นไป รวมถึงออบเจ็กต์ที่ซับซ้อนหรืออาร์เรย์อื่นๆ ค่าที่จัดเก็บไว้ในอาร์เรย์ บางครั้งเรียกว่า "องค์ประกอบ" ของอาร์เรย์

สร้างอาร์เรย์

การสร้างอาร์เรย์มี 2 วิธี เช่นเดียวกับประเภทข้อมูลแบบพื้นฐาน หรือการสร้างอาร์เรย์แบบลิเทอรัล หรือโดยการเรียกใช้ตัวสร้าง Array() ในตัวของ JavaScript ด้วย new Array() การกำหนดอาร์เรย์ให้กับตัวแปรเป็นวิธีที่พกพาได้ง่ายและทำซ้ำในการกำหนดหลายค่าให้กับตัวระบุเดียว

ไวยากรณ์ลิเทอรัลของอาร์เรย์ใช้ชุดวงเล็บ ([]) ล้อมรอบค่าข้อมูลที่คั่นด้วยเครื่องหมายจุลภาคอย่างน้อย 0 รายการ ดังนี้

const myArray = [];

ไวยากรณ์ตัวสร้างอาร์เรย์ใช้ออบเจ็กต์ Array ในตัวของ JavaScript เป็นตัวสร้างที่มีคีย์เวิร์ด new ดังนี้

const myArray = new Array();

ทั้งไวยากรณ์ลิเทอรัลของอาร์เรย์และตัวสร้างอาร์เรย์จะช่วยให้คุณเติมข้อมูลอาร์เรย์ด้วยข้อมูลที่สร้างขึ้นได้ แม้ว่าไวยากรณ์จะแตกต่างไปเล็กน้อยตามวิธีกำหนดค่าเหล่านั้น ไวยากรณ์ลิเทอรัลของอาร์เรย์ใช้ค่าที่คั่นด้วยคอมมาระหว่างวงเล็บ ซึ่งดูเหมือนกับอาร์เรย์ผลลัพธ์

const myArray = [ true, null, "String", false ];

myArray;
> [ true, null, "String", false ]

ไวยากรณ์ตัวสร้างอาร์เรย์ใช้ค่าที่คั่นด้วยคอมมาเป็นอาร์กิวเมนต์ โดยมีข้อยกเว้นพิเศษด้านลักษณะการทำงาน 1 ประการดังนี้

const myArray = new Array( true, null, "String", false );

myArray;
> Array(4) [ true, null, "String", false ]

เมื่อมีการส่งค่าตัวเลขค่าเดียวไปยังตัวสร้าง Array ระบบจะไม่กำหนดค่านั้นให้กับตำแหน่งที่ 0 ในอาร์เรย์ผลลัพธ์ แต่จะสร้างอาร์เรย์ด้วยจำนวนช่องว่างสำหรับค่าดังกล่าว ซึ่งจะไม่สร้างข้อจำกัด ใดๆ กับอาร์เรย์ คุณจะเพิ่มและนำรายการออกจากรายการได้ด้วยวิธีเดียวกันกับการใช้อาร์เรย์ลิเทอรัล

// Firefox:\
const myArray = new Array( 10 );

myArray;
> Array(10) [ <10 empty slots> ]
// Chrome:
const myArray = new Array( 10 );

myArray;
> (10) [empty × 10]

อาร์เรย์ที่มีช่องโฆษณาว่าง (บางครั้งเรียกว่า "sparse Array") เป็นกรณีพิเศษ แทนที่จะใส่ค่า undefined หรือค่า null ที่ชัดแจ้ง ช่องว่างก็มักเป็นค่าเดี่ยวแต่ก็ไม่เสมอไปที่จะถือว่าเป็นค่า undefined ในที่อื่นๆ ในภาษานั้น

คุณสร้างอาร์เรย์แบบกะทัดรัดโดยไม่ได้ตั้งใจโดยใช้ไวยากรณ์ของอาร์เรย์ลิเทอรัลได้โดยละเว้นค่าระหว่างเครื่องหมายจุลภาคเมื่อคุณสร้างอาร์เรย์ลิเทอรัล ดังนี้

const myArray = [ true,, true, false ];

myArray;
> Array(4) [ true, <1 empty slot>, true, false ]

แม้ว่าระบบจะไม่ได้ถือว่าเป็นค่าที่มีความหมายในทุกบริบท แต่ช่องโฆษณาว่างก็เป็นปัจจัยในการพิจารณาความยาวทั้งหมดของอาร์เรย์ ซึ่งอาจทำให้ได้ผลลัพธ์ที่ไม่คาดคิดเมื่อทำซ้ำค่าของอาร์เรย์

const myArray = [ 1,, 3, 4 ];

myArray.length;
> 4

for( const myValue of myArray ) {
  console.log( myValue + 10 );
}
> 11
> NaN
> 13
> 14

ลักษณะการทำงานนี้มาจากการตัดสินใจออกแบบ JavaScript ครั้งแรกบางส่วน หลีกเลี่ยงการใช้อาร์เรย์ที่กระจัดกระจายในการพัฒนาสมัยใหม่

อาร์เรย์แบบตรงตัวจะรับค่าพร็อพเพอร์ตี้และเมธอดจากตัวสร้างที่สอดคล้องกัน เช่นเดียวกับแบบพื้นฐาน เนื่องจากอาร์เรย์เป็นออบเจ็กต์รูปแบบพิเศษ ไวยากรณ์ของอาร์เรย์และไวยากรณ์ new Array() จะสร้างผลลัพธ์ที่มีฟังก์ชันการทำงานที่เหมือนกันทุกประการ ซึ่งเป็นออบเจ็กต์ที่สืบทอดต้นแบบมาจากตัวสร้าง Array

const arrayLiteral = [];
const arrayConstructor = new Array();

typeof arrayLiteral;
> "object"

arrayLiteral;
> Array []
    length: 0
    <prototype>: Array []

typeof arrayConstructor;
> "object"

arrayConstructor;
> Array []
    length: 0
    <prototype>: Array []

เนื่องจากผลลัพธ์ทั้ง 2 รายการเหมือนกัน และไวยากรณ์ของอาร์เรย์มีความกระชับและตรงมากขึ้น เราจึงขอแนะนําอย่างยิ่งให้ใช้ไวยากรณ์ตามตัวอักษรของอาร์เรย์แทนไวยากรณ์ new Array() เสมอ

เข้าถึงค่าอาร์เรย์

คุณเข้าถึงองค์ประกอบแต่ละรายการภายในอาร์เรย์ได้โดยใช้เครื่องหมายวงเล็บเหลี่ยม ([]) ที่ตามหลังอาร์เรย์หรือตัวระบุที่มีตัวเลขซึ่งอ้างอิงถึงดัชนีขององค์ประกอบนั้น


[ "My string", "My other string" ][ 1 ];
> "My other string"

const myArray = [ "My string", 50, true ];

myArray[ 0 ];
> "My string"

myArray[ 1 ];
> 50

myArray[ 2 ];
> true

อาร์เรย์ใน JavaScript ไม่เป็นแบบเชื่อมโยง ซึ่งหมายความว่าคุณจะใช้สตริงที่กำหนดเองเป็นดัชนีไม่ได้ อย่างไรก็ตาม ระบบจะเปลี่ยนค่าตัวเลขที่ใช้เข้าถึงองค์ประกอบในอาร์เรย์เป็นค่าสตริงที่ทำงานอยู่เบื้องหลัง ซึ่งหมายความว่าคุณจะใช้ค่าสตริงที่มีเฉพาะอักขระตัวเลขได้ ดังนี้

const myArray = [ "My string", 50, true ];

myArray[ 2 ];
> true

myArray[ "2" ];
> true

การพยายามเข้าถึงองค์ประกอบที่อยู่นอกขอบเขตที่กำหนดไว้ในอาร์เรย์จะทำให้ได้ผลลัพธ์เป็น undefined ไม่ใช่ข้อผิดพลาด

const myArray = [ "My string", 50, true ];

myArray[ 9 ];
> undefined

การกำหนดโครงสร้าง

การทำลายการกำหนดเป็นวิธีที่กระชับในการดึงช่วงของค่าจากอาร์เรย์หรือออบเจ็กต์ และมอบหมายให้กับชุดตัวระบุ บางครั้งกระบวนการเรียกว่า "การคลายการแพคข้อมูล" โครงสร้างข้อมูลดั้งเดิม แม้ว่าการดำเนินการดังกล่าวจะไม่เป็นการแก้ไขอาร์เรย์หรือออบเจ็กต์ต้นฉบับ

การกำหนดโครงสร้างจะใช้รายการตัวระบุแบบอาร์เรย์หรือออบเจ็กต์เพื่อติดตามค่า ในรูปแบบที่ง่ายที่สุดซึ่งเรียกว่า รูปแบบการเชื่อมโยง การถอดรหัส แต่ละค่าจะถูกคลายแพคจากอาร์เรย์หรือออบเจ็กต์และกำหนดให้กับตัวแปรที่สอดคล้องกัน โดยเริ่มต้นโดยใช้ let หรือ const (หรือ var)

const myArray = [ "A string", "A second string" ];
const [ myFirstElement, mySecondElement ] = myArray;

const myObject = { firstValue: false, secondValue: true };
const { myProp, mySecondProp } = myObject;

myFirstElement;
> "My string"

mySecondElement;
> "Second string"

myProp;
> false

mySecondProp;
> true

ใช้วงเล็บปีกกา ({}) เพื่อทำลายวัตถุ และใช้วงเล็บเหลี่ยม ([]) เพื่อทำลายอาร์เรย์

const myArray = [ false, true ];
const myObject = { firstValue: false, secondValue: true };

const [ myProp, mySecondProp ] = myObject;
> Uncaught TypeError: myObject is not iterable

const { myElement, mySecondElement } = myArray;

myElement
> undefined

mySecondElement;
> undefined

การทำลายอาร์เรย์เกิดขึ้นตามลำดับจากซ้ายไปขวา ตัวระบุแต่ละตัวในการกำหนดโครงสร้างจะสอดคล้องกับองค์ประกอบของอาร์เรย์ที่มีดัชนีเดียวกัน

const myArray = [ 1, 2, 3 ];
const [ myElement, mySecondElement, myThirdElement ] = myArray;

myElement;
> 1

mySecondElement;
> 2

myThirdElement;
> 3

ยังเป็นการทำงานเริ่มต้นเมื่อทำลายวัตถุด้วย อย่างไรก็ตาม หากตัวระบุที่ใช้ในการกำหนดโครงสร้างตรงกับคีย์ของพร็อพเพอร์ตี้ของออบเจ็กต์ ระบบจะใส่ค่าพร็อพเพอร์ตี้ที่เกี่ยวข้องให้กับตัวระบุเหล่านั้นโดยไม่คำนึงถึงลำดับที่ระบุไว้

const myObject = { firstValue: 1, secondValue: 2, thirdValue 3 };
const { secondValue, thirdValue, firstValue } = myObject;

firstValue;
> 1

secondValue;
> 2

thirdValue;
> 3

คุณสามารถข้ามองค์ประกอบได้โดยการละเว้นตัวระบุ

const myArray = [ 1, 2, 3 ];
const [ firstValue,, secondValue ] = myArray;

firstValue;
> 1

secondValue;
> 3

การทำลายไวยากรณ์ยังช่วยให้คุณกำหนดค่าเริ่มต้นได้ในกรณีที่ค่าที่ยกเลิกโครงสร้างเป็นช่องที่ว่างเปล่า เช่น ในกรณีของอาร์เรย์แบบกระจัดกระจายหรือค่า undefined

const myArray = [ true, ];
const [ firstValue = "Default string.", secondValue = "Default string." ] = myArray;

firstValue;
> true

secondValue;
> "Default string."

การทำลายไม่ได้บังคับให้ค่าเป็นประเภทใดประเภทหนึ่ง ซึ่งหมายความว่าค่า "falsy" เช่น สตริงว่าง ("") หรือ null จะยังคงถือว่าเป็นค่าที่มีความหมายที่แยกตัวแล้ว ดังนี้

const myArray = [ false, null, 0, "",, undefined ];
const [ falseValue = true, nullValue = true, zeroValue = true, emptyStringValue = true, emptySlot = true, undefinedValue = true ] = myArray;

falseValue;
> false;

nullValue;
> null

zeroValue;
> 0

emptyStringValue;
> ""

emptySlot;
> true

undefinedValue;
> true

โอเปอเรเตอร์การกระจาย

ใช้โอเปอเรเตอร์การกระจาย (...) ที่นำมาใช้ใน ES6 เพื่อขยายโครงสร้างข้อมูลที่ทำซ้ำได้ เช่น อาร์เรย์ สตริง หรือ Object Litel ให้เป็นองค์ประกอบเดี่ยว โอเปอเรเตอร์การกระจายจะตามด้วยโครงสร้างข้อมูลที่ต้องการขยาย หรือตัวระบุของตัวแปรที่มีโครงสร้างข้อมูลดังกล่าว

const myArray = [ 1, 2, 3 ];

console.log( ...myArray );
> 1 2 3

ไวยากรณ์การกระจายจะใช้ในการคัดลอกและรวมอาร์เรย์เป็นหลัก

const myArray = [ 4, 5, 6 ];
const mySecondArray = [1, 2, 3, ...myArray ];

mySecondArray;
> Array(6) [ 1, 2, 3, 4, 5, 6 ]

คุณสามารถใช้ไวยากรณ์การกระจายได้ในบริบทต่อไปนี้เท่านั้น

สำหรับอาร์เรย์และสตริง ไวยากรณ์การกระจายจะใช้ก็ต่อเมื่อควรมีอาร์กิวเมนต์ 0 ขึ้นไปในการเรียกใช้ฟังก์ชันหรือองค์ประกอบในอาร์เรย์ ตัวอย่างแรกของไวยากรณ์โอเปอเรเตอร์การเผยแพร่ในส่วนนี้ใช้งานได้เพราะส่งผ่าน ...myArray เป็นอาร์กิวเมนต์ไปยังเมธอด console.log ในตัว

เช่น คุณไม่สามารถกำหนดข้อมูลที่กระจายไปยังตัวแปรนอกอาร์เรย์อื่น ดังนี้

const myArray = [ 1, 2, 3 ];
const spreadVariable = ...myArray;
> Uncaught SyntaxError: Unexpected token '...'

แต่คุณคัดลอกอาร์เรย์โดยการกระจายอาร์เรย์เดิมลงในอาร์เรย์ลิเทอรัล ดังนี้

const myArray = [ 1, 2, 3 ];
const spreadArray = [ ...myArray ];

spreadArray;
> Array(3) [ 1, 2, 3 ]

วิธีผสานองค์ประกอบที่ประกอบกันเป็นอาร์เรย์ตั้งแต่ 2 รายการขึ้นไปเข้าเป็นอาร์เรย์เดียว

const myArray = [ 1, 2, 3 ];
const mySecondArray = [ 4, 5, 6 ];
const myNewArray = [ ...myArray, ...mySecondArray ];

myNewArray;
> Array(6) [ 1, 2, 3, 4, 5, 6 ]

หรือหากต้องการส่งองค์ประกอบของอาร์เรย์เป็นอาร์กิวเมนต์แต่ละรายการในการเรียกใช้ฟังก์ชัน ให้ทำดังนี้

const myArray = [ true, false ];
const myFunction = ( myArgument, mySecondArgument ) => {
    console.log( myArgument, mySecondArgument );
};

myFunction( ...myArray );
> true false

เราได้ขยายตัวโอเปอเรเตอร์การกระจายให้ทำงานร่วมกับลิเทอรัลออบเจ็กต์ใน ES2018 เช่นเดียวกับอาร์เรย์ คุณสามารถใช้โอเปอเรเตอร์การแพร่กระจายเพื่อทำซ้ำหรือผสานออบเจ็กต์ได้ ดังนี้

const myObj = { myProperty : true };
const mySecondObj = { ...myObj };

mySecondObj;
> Object { myProperty: true }
const myFirstObj = { myProperty : true };
const mySecondObj = { additionalProperty : true };
const myMergedObj = { ...myFirstObj, ...mySecondObj };

myMergedObj;
> Object { myProperty: true, additionalProperty: true }

โอเปอเรเตอร์การกระจายสร้างสำเนา "ตื้น" ซึ่งหมายความว่าโมเดลจะไม่คัดลอกต้นแบบและคุณสมบัติที่แจกแจงไม่ได้ของออบเจ็กต์ต้นฉบับ

const myCustomPrototype = { protoProp: "My prototype." };
const myObj = Object.create( myCustomPrototype, {
    myEnumerableProp: {
        value: true,
        enumerable: true
    },
    myNonEnumerableProp: {
        value: false,
        enumerable: false
    }
});
const myNewObj = { ...myObj };

myObj;
> Object { myEnumerableProp: true, … }
    myEnumerableProp: true
    myNonEnumerableProp: false
    <prototype>: Object { protoProp: "My prototype." }

myNewObj;
> Object { myEnumerableProp: true }
    myEnumerableProp: true
    <prototype>: Object { … }

โปรดทราบว่าอาร์เรย์และออบเจ็กต์ไม่สามารถใช้แทนกันได้ คุณไม่สามารถกระจายออบเจ็กต์ลงในอาร์เรย์หรืออาร์เรย์ลงในออบเจ็กต์ได้

โอเปอเรเตอร์ REST

แม้ว่าไวยากรณ์ของโอเปอเรเตอร์จะเหมือนกัน แต่โอเปอเรเตอร์ส่วนที่เหลือ (...) จะทำหน้าที่ตรงข้ามตามบริบทที่ใช้ แทนที่จะขยายโครงสร้างข้อมูลที่ทำซ้ำได้เป็นองค์ประกอบเดี่ยวๆ เหมือนที่ทำในการทำลายการกำหนดหรือเป็นพารามิเตอร์ฟังก์ชัน โอเปอเรเตอร์ที่เหลือจะรวมองค์ประกอบต่างๆ เข้าไว้ในโครงสร้างข้อมูลที่ทำซ้ำได้ ชื่อมาจากข้อเท็จจริงที่ว่า ใช้รวบรวม "ส่วนที่เหลือ" ของชุดค่าข้อมูล

เมื่อใช้กับการกำหนดโครงสร้าง ไวยากรณ์เรียกว่าไวยากรณ์ "พร็อพเพอร์ตี้ส่วนที่เหลือ"

const myArray = [ "First", "Second", "Third", "Fourth", "Fifth" ];

[ myFirstElement, mySecondElement, ...remainingElements ] = myArray;

myFirstElement;
> "First"

mySecondElement;
> "Second"

remainingElements;
> Array(3) [ "Third", "Fourth", "Fifth"]

เมื่อใช้สำหรับระบุอาร์กิวเมนต์จำนวนไม่จำกัดในฟังก์ชัน ไวยากรณ์จะเรียกว่าไวยากรณ์ "พารามิเตอร์ส่วนที่เหลือ"

function myFunction( ...myParameters ) {
    let result = 0;
    myParameters.forEach( ( myParam ) => {
        result += myParam;
    });
    return result;
};

myFunction( 2, 2 );
> 4

myFunction( 1, 1, 1, 10, 5 );
> 18

myFunction( 10, 11, 25 );
> 46

%TypedArray%

อาร์เรย์ประเภทเป็นฟีเจอร์ ES6 ที่ออกแบบมาเพื่อจัดเก็บข้อมูลไบนารีที่มีโครงสร้าง เช่น เมื่อทำงานกับไฟล์ที่อัปโหลดหรือ WebGL

เช่นเดียวกับสัญลักษณ์ %TypedArray%ฟังก์ชันภายใน (โดยปกติจะแสดงเป็น %TypedArray% หรือ @@TypedArray ดังนั้นเพื่อไม่ให้เข้าใจผิดว่าเป็นพร็อพเพอร์ตี้ส่วนกลาง) ไม่ใช่ฟังก์ชันตัวสร้างตามปกติ และคุณจะเรียกใช้ด้วย new หรือเรียกใช้โดยตรงไม่ได้ แต่ %TypedArray% จะหมายถึง Superclass ระดับบนสุดของเครื่องมือสร้างเดี่ยว ซึ่งแต่ละรายการใช้งานได้กับรูปแบบข้อมูลไบนารีที่เฉพาะเจาะจง Superclass ภายใน %TypedArray% จะมีพร็อพเพอร์ตี้และเมธอดยูทิลิตีที่คลาสย่อยของตัวสร้าง %TypedArray% และอินสแตนซ์ทั้งหมดรับค่ามา

ทดสอบความเข้าใจ

เมื่อ "const myArray = [ 30, 50, 70 ];` `myArray[1]` แสดงผลอะไร

50
30
70

หาก "myArray" มี 3 ค่า จะ "myArray[9]" แสดงผลอย่างไร

Undefined
ข้อความแสดงข้อผิดพลาด
9
Null