JavaScript
Arrays
shift / unshift
เรียนรู้ shift() และ unshift() — สอง method สำหรับเพิ่มและลบ element หน้าสุดของ Array ตั้งแต่ unshift() เพิ่มที่หน้า (return length), shift() ดึงหน้าสุดออก (return element), การ reindex ข้อมูลทั้งหมด, เทียบ push/pop vs unshift/shift, และสร้าง queue แบบ FIFO ผ่าน Lab 3 ข้อ
`unshift()` — เพิ่ม element หน้าสุดของ Array
unshift() เป็น method ใน array ใช้เพิ่ม element หน้าสุดของ array — หนึ่ง element ขึ้นไป คล้ายกับ push() แต่ทำงานที่ index 0 แทนที่จะเป็น index สุดท้าย สิ่งที่ต้องรู้: • unshift() รับกี่ argument ก็ได้ เหมือน push() • คืนค่า (return) เป็น length ใหม่ของ array • มัน mutate array ต้นฉบับโดยตรง • ทุก element เดิมจะเลื่อน index ไปทางขวา (0→1, 1→2, ...) — ต้อง reindex ใหม่ทั้งหมด
const fruits = ["กล้วย", "ส้ม"];
// index: 0 1
const newLen = fruits.unshift("แอปเปิ้ล");
console.log(newLen); // 3 ← return คือ length ใหม่
console.log(fruits); // ["แอปเปิ้ล", "กล้วย", "ส้ม"]
// "แอปเปิ้ล" กลายเป็น index 0
// "กล้วย" เลื่อนจาก 0 → 1
// "ส้ม" เลื่อนจาก 1 → 2เวลาดูโค้ดนี้ให้สังเกต: "แอปเปิ้ล" ถูกเพิ่มที่หน้า (index 0) — ไม่ใช่ต่อท้าย และ element เดิมทุกตัว index เพิ่มขึ้น 1 เพราะถูกผลักไปทางขวา นี่คือข้อแตกต่างหลักกับ push(): push เพิ่มที่ท้ายแบบไม่กระทบ index อื่น แต่ unshift กระทบทุก index
const nums = [3, 4, 5];
// unshift หลาย element — เพิ่มหน้าตามลำดับที่ใส่ argument
const len = nums.unshift(1, 2);
console.log(len); // 5 ← length ใหม่
console.log(nums); // [1, 2, 3, 4, 5]
// 1 อยู่ index 0, 2 อยู่ index 1 → เรียงตามลำดับ argument ที่เราใส่สำคัญ: ลำดับของ argument ใน unshift(1, 2) จะปรากฏใน array เป็น [1, 2, ...] ตามลำดับที่ใส่ — ตัวที่ใส่อันแรกจะอยู่ index 0 ตัวที่สองอยู่ index 1 ไปเรื่อย ๆ
unshift() เพิ่มที่หน้า → ทุก element เลื่อนขวา (index +1) / shift() ดึงหน้าสุดออก → ทุก element เลื่อนซ้าย (index -1)
`shift()` — ดึง element หน้าสุดออก
shift() เป็น method ใน array ใช้ดึง element สุดแรก (index 0) ออกจาก array — คล้ายกับ pop() แต่ทำงานที่หน้าแทนที่จะทำงานที่ท้าย สิ่งที่ต้องรู้: • shift() ไม่รับ argument — ดึงทีละ 1 element เสมอ • คืนค่า (return) เป็น element ที่ถูกดึงออก • มัน mutate array ต้นฉบับโดยตรง • ทุก element ที่เหลือเลื่อน index ไปทางซ้าย (1→0, 2→1, ...) — เพราะต้องถมช่องว่างที่ index 0
const queue = ["A", "B", "C"];
// index: 0 1 2
const first = queue.shift();
console.log(first); // "A" ← return คือ element ที่ถูกดึงออก
console.log(queue); // ["B", "C"]
// "B" เลื่อนจาก index 1 → 0
// "C" เลื่อนจาก index 2 → 1
console.log(queue.length); // 2shift() ดึงแค่ element แรกออก (index 0) — element ที่เหลือทุกตัวใน array ถูกเลื่อนซ้ายเพื่อเติมช่องว่าง ทำให้ index เปลี่ยนทั้ง array เช่นเดียวกับ unshift() สังเกต: shift() บน array เปล่าได้ undefined เหมือน pop() — ไม่ throw error
const items = ["X"];
const removed = items.shift();
console.log(removed); // "X"
console.log(items); // [] — array เปล่า
// shift() บน array เปล่า → undefined
const nothing = items.shift();
console.log(nothing); // undefined ← ไม่ error แต่ได้ undefinedเหมือน pop() เวลาใช้บน array เปล่า — shift() ก็ return undefined โดยไม่ throw error เช่นกัน ถ้าโค้ดของเราคาดหวังว่า shift() ต้องได้ค่าเสมอ อาจเกิด bug แบบเงียบ ๆ
เปรียบเทียบ push/pop กับ unshift/shift
push/pop และ unshift/shift เป็น method ที่เป็นคู่กัน — วิธีจำง่าย ๆ: push↔unshift (เพิ่ม) และ pop↔shift (ดึงออก) ต่างกันที่ทำงานที่ปลายคนละด้านของ array ตารางด้านล่างสรุปความแตกต่าง + ข้อควรรู้สำคัญ
| เรื่อง | push() / pop() | unshift() / shift() |
|---|---|---|
| ทำงานที่ | index ท้ายสุด (right side) | index 0 (left side / หน้าสุด) |
| push / unshift รับ argument | รับกี่ตัวก็ได้ | รับกี่ตัวก็ได้ |
| push / unshift return | return length ใหม่ | return length ใหม่ |
| pop / shift return | return element ที่ถูกดึง | return element ที่ถูกดึง |
| pop / shift รับ argument | ไม่รับ argument | ไม่รับ argument |
| mutate array | ใช่ — เปลี่ยน array ต้นฉบับทั้งคู่ | ใช่ — เปลี่ยน array ต้นฉบับทั้งคู่ |
| ผลกระทบกับ index อื่น | push/pop แทบไม่กระทบ — แค่เปลี่ยน length | unshift/shift กระทบทุก index — เพราะข้อมูลต้องเลื่อน |
| ความเร็ว (performance) | push/pop เร็ว (O(1)) — ไม่ต้องย้ายข้อมูลอื่น | unshift/shift ช้า (O(n)) — ต้อง reindex ข้อมูลทั้งหมด |
กฎการเลือกใช้: • ถ้าต้องการเพิ่ม/ลบที่ท้าย → push/pop (เร็วและตรงไปตรงมา) • ถ้าต้องการเพิ่ม/ลบที่หน้า → unshift/shift (แต่รู้ไว้ว่าช้าสำหรับ array ใหญ่) • ถ้าต้องการ queue (FIFO — เข้าก่อนออกก่อน) → ใช้ push + shift หรือ unshift + pop • ถ้าต้องการ stack (LIFO — เข้าหลังออกก่อน) → ใช้ push + pop (เหมือนที่เราเรียนในบทก่อน)
จุดที่มือใหม่มักพลาด
- unshift() return length ไม่ใช่ array — เหมือน push() เลย มือใหม่มักคิดว่า chain ได้แต่ chain ไม่ได้เพราะ return เป็น number
- shift() return element ไม่ใช่ array — shift ดึง element แรกออก 1 ตัวแล้วคืนค่านั้น ถ้าอยากได้ array หลัง shift ต้องอ่านจากตัวแปร array โดยตรง
- unshift/shift mutate ต้นฉบับ — ทั้งคู่เปลี่ยน array โดยตรง ไม่ได้สร้าง array ใหม่ ถ้าต้องการเก็บค่าเดิมไว้ต้อง copy ก่อน เช่น const copy = arr.concat()
- shift() ไม่รับ argument — arr.shift(2) จะไม่ shift 2 ตัว (shift ดึงทีละ 1 ตัวเสมอ) argument ที่ใส่ไปจะถูกละทิ้ง
- unshift/shift กระทบ index ทุกตัว — ข้อมูลอื่นย้ายตำแหน่งทั้งหมด ระวังถ้ามีโค้ดที่อ้างอิง index เก่าอยู่
- ลำดับ argument ใน unshift — unshift(1, 2) ได้ [1, 2, ...] เรียงตามลำดับที่ใส่ argument ตัวแรกอยู่ index 0