WEB · บทที่ 3 JavaScript

หัวข้อ 9 · 18 นาที

Array พื้นฐาน

นึกภาพก่อน

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

พื้นฐาน

  • array เป็นตัวแปรที่ เก็บได้หลายค่า แต่ละค่าเรียกว่า element
  • เข้าถึง element ด้วย หมายเลขตำแหน่ง เรียกว่า index
    • ต่างจาก object ที่ใช้ ชื่อ (เรียกว่า key)
  • ใน JavaScript array เป็น object

เข้าถึง element

js
const cars = ["Toyota", "Honda", "BMW", "Tesla", "Lexus"];

// Index of the first element is 0 (zero)
console.log(cars[0]);                 // Toyota
console.log(cars[1]);                 // Honda
const index = 0;
console.log(cars[index]);             // Toyota

// Trying to access element that does not exist
console.log(cars[9]);                 // undefined

// Using arr.length property
console.log(cars.length);             // 5
console.log(cars[cars.length]);       // undefined
console.log(cars[cars.length - 1]);   // Lexus
ข้อเท็จจริงค่า
index ตัวแรก0
index ตัวสุดท้ายlength − 1
เข้าถึง index ที่ไม่มีundefined (ไม่ error)
lengthproperty (ไม่มีวงเล็บ) = จำนวน element

Method ชุดที่ 1: เพิ่มและลบ

Methodทำที่ทำอะไรคืนค่า
push(el)ท้ายเพิ่มความยาวใหม่
pop()ท้ายลบelement ที่ถูกลบ
unshift(el)หน้าเพิ่มความยาวใหม่
shift()หน้าลบelement ที่ถูกลบ
js
const cars = ["Toyota", "Honda", "BMW", "Tesla", "Lexus"];

cars.push("Suzuki")   // [..., "Lexus", "Suzuki"]
cars.pop()            // เอา "Suzuki" ออก
cars.pop()            // เอา "Lexus" ออก

const selectedCar = cars.shift()   // selectedCar = "Toyota"
cars.unshift("Lambo")              // ["Lambo", "Honda", ...]

ทั้งสี่ตัว แก้ array เดิม (mutate) และใช้กับ array ที่ประกาศด้วย const ได้ เพราะไม่ได้กำหนดค่าใหม่ให้ตัวแปร

วิธีจำ: push / pop ทำที่ ท้าย · shift / unshift ทำที่ หน้า (ตัวที่ชื่อยาวกว่าคือ "เพิ่ม")

ขั้นที่ 1 / 7เริ่มต้น

ค่าเริ่มต้นของ array

push x, pop, shift, unshift x, get i, length, includes x, slice a b

  1. [0]
  2. [1]
  3. [9]
  4. length
  5. [5]
  6. [4]

0

Toyota

1

Honda

2

BMW

3

Tesla

4

Lexus

cars.length = 5 · index สุดท้าย = 4

เขียว = array ถูกแก้สีเน้น = อ่านค่า
1.0×

คำอธิบายทีละขั้น

array และ index

array เก็บได้หลายค่า (element) เข้าถึงด้วยหมายเลขตำแหน่ง (index) ที่เริ่มจาก 0 ตัวเลขเหนือกล่องคือ index ของแต่ละ element

typeof กับ Array.isArray()

js
const cars = ["Honda", "BMW"];
const user = { name: "John Ive", age: 33 }
const isAlive = true;
const msg = "Running..."

console.log(typeof cars)             // object
console.log(typeof user)             // object
console.log(typeof isAlive)          // boolean
console.log(typeof msg)              // string
console.log(Array.isArray(cars))     // true
console.log(Array.isArray(user))     // false

typeof บอกว่า array เป็น "object" (เพราะ array เป็น object) จึง แยก array ออกจาก object ธรรมดาไม่ได้ ต้องใช้ Array.isArray()

วน loop

js
const cars = ["Toyota", "Honda", "BMW", "Tesla", "Lexus"];

// แบบที่ 1: for กับ length
for (let i = 0; i < cars.length; i++) {
  console.log(i, "is", cars[i]);
}

// แบบที่ 2: forEach
cars.forEach((el, idx, arr) => {
  console.log(el, idx, arr);
});
  • เงื่อนไขคือ i < cars.length (ไม่ใช่ <=) เพราะ index สุดท้ายคือ length − 1
  • ใช้ cars.length แทนเลขตายตัว (เช่น 5) เพื่อให้โค้ดยังถูกเมื่อ array เปลี่ยนขนาด
  • callback ของ forEach ได้รับสามค่าตามลำดับ: element, index, array ทั้งตัว

Array destructuring

ดึงค่าจาก array ออกมาเป็นตัวแปรตาม ตำแหน่ง:

js
const cars = ["Toyota", "Honda", "BMW", "Tesla", "Lexus"];
const [car1, car2] = cars;      // car1 = "Toyota", car2 = "Honda"

const [, second] = cars;        // ข้ามตัวแรก: second = "Honda"
const [,, third] = cars;        // ข้ามสองตัว: third = "BMW"

comma ที่เว้นว่างคือการข้ามตำแหน่ง

Method ชุดที่ 2

Methodทำอะไรแก้ array เดิมไหม
arr1.concat(arr2, arr3)ต่อหลาย array เป็น array ใหม่ไม่
arr.join(separator)เชื่อมทุก element เป็น stringไม่
arr.includes(el, start)มี element นี้หรือไม่ (เริ่มค้นที่ index start)ไม่
arr.slice(start, end)ตัดส่วนของ array ตั้งแต่ start ถึง ก่อน endไม่
js
const fruits = ["Banana", "Apple"]
const fruits2 = ["Orange"]
const fruits3 = ["Pineapple", "Mango"]

const allFruits = fruits.concat(fruits2, fruits3)
// ["Banana", "Apple", "Orange", "Pineapple", "Mango"]

allFruits.join(" | ")            // "Banana | Apple | Orange | Pineapple | Mango"

allFruits.includes("Banana")     // true
allFruits.includes("banana")     // false  ← case-sensitive
allFruits.includes("Banana", 1)  // false  ← เริ่มค้นที่ index 1 จึงไม่เจอตัวที่ index 0

let newFruits = allFruits.slice(2)
// ["Orange", "Pineapple", "Mango"]   allFruits ไม่เปลี่ยน

newFruits = allFruits.slice(2, allFruits.length)   // ผลเหมือนกัน

ตัวอย่างไล่ทีละขั้น

โจทย์: หลังจบโค้ดนี้ q, a, b และ n มีค่าอะไร

js
const q = ["A", "B", "C"];
q.push("D");
const a = q.shift();
q.unshift("Z");
const b = q.pop();
const n = q.length;
บรรทัดq หลังทำคืนค่า
เริ่ม["A", "B", "C"]
q.push("D")["A", "B", "C", "D"]4
q.shift()["B", "C", "D"]"A" → a
q.unshift("Z")["Z", "B", "C", "D"]4
q.pop()["Z", "B", "C"]"D" → b

คำตอบ: q = ["Z", "B", "C"], a = "A", b = "D", n = 3

จุดที่มักพลาด

1. คิดว่า index เริ่มที่ 1

เริ่มที่ 0 ตัวสุดท้ายคือ length - 1

2. คิดว่าเข้าถึง index ที่ไม่มีแล้ว error

ได้ undefined

3. สลับ push/pop กับ shift/unshift

push/pop = ท้าย · shift/unshift = หน้า

4. ใช้ typeof ตรวจ array

ได้ "object" ต้องใช้ Array.isArray()

5. คิดว่า slice แก้ array เดิม

คืน array ใหม่ และ ไม่รวม index end

6. คิดว่า includes ไม่สนตัวพิมพ์

case-sensitive

7. เขียน i <= arr.length ใน for

รอบสุดท้ายจะได้ undefined

ที่มา: JavaScript - Array.pdf หน้า 1–4