JavaScript
String Methods
slice / substring
เรียนรู้ slice() และ substring() — สอง method สำหรับดึง substring จาก string ตั้งแต่การทำงานพื้นฐาน, negative index ของ slice(), การสลับ argument อัตโนมัติของ substring(), ตารางเปรียบเทียบความแตกต่าง, ไปจนถึงการใช้งานจริงเช่นดึงนามสกุลไฟล์, ดึงชื่อผู้ใช้จาก email, และดึง N ตัวสุดท้าย ผ่าน Lab 4 ข้อ
`slice()` คืออะไร — ดึงส่วนของ string ด้วย index เริ่มต้นและสิ้นสุด
`slice()` เป็น method บน string ใช้ดึง substring ออกมา โดยระบุตำแหน่งเริ่มต้น (`startIndex`) และตำแหน่งสิ้นสุด (`endIndex` — ไม่รวมตำแหน่งนี้) — คืนค่าเป็น string ใหม่ โดยไม่เปลี่ยน string ต้นฉบับ สิ่งที่ต้องรู้: • `slice(startIndex, endIndex)` — ดึงจากตำแหน่ง `startIndex` ถึง `endIndex - 1` • `endIndex` เป็น optional — ถ้าไม่ระบุ จะดึงไปจนจบ string • รับค่า negative index ได้ — `-1` หมายถึงตัวสุดท้าย, `-2` หมายถึงตัวก่อนสุดท้าย • คืนค่าเป็น string ใหม่ — string ต้นฉบับไม่เปลี่ยน (immutable) • ถ้า `startIndex >= endIndex` → คืน `""` (empty string)
const text = "hello world";
// slice(0, 5) — ดึงจาก index 0 ถึง 4 (ไม่รวม 5)
console.log(text.slice(0, 5)); // "hello"
// slice(6) — ดึงจาก index 6 ถึงจบ
console.log(text.slice(6)); // "world"
// slice() — ไม่ระบุอะไรเลย = copy ทั้ง string
console.log(text.slice()); // "hello world"
// ต้นฉบับไม่เปลี่ยน
console.log(text); // "hello world"const text = "hello world";
// slice(-5) — ดึง 5 ตัวสุดท้าย
console.log(text.slice(-5)); // "world"
// slice(0, -6) — ดึงตั้งแต่ index 0 ถึงตำแหน่งก่อน 6 ตัวสุดท้าย
console.log(text.slice(0, -6)); // "hello"
// slice(-5, -1) — ดึงจากตัวที่ 5 จากท้าย ถึงก่อนตัวสุดท้าย
console.log(text.slice(-5, -1)); // "worl"
// slice(-3, -1) — 3 ตัวท้ายแต่ไม่รวมตัวสุดท้าย
console.log(text.slice(-3, -1)); // "rl"- `slice(start, end)` — ดึงจากตำแหน่ง `start` ถึง `end - 1` (ไม่รวม `end`)
- ถ้าไม่ระบุ `end` — ดึงไปจนจบ string
- negative index — `-1` คือตัวสุดท้าย, `-2` คือก่อนสุดท้าย ใช้สะดวกเวลาไม่รู้ความยาว string
- ถ้า `start >= end` — คืน empty string `""`
- คืน string ใหม่ — ต้นฉบับไม่เปลี่ยน
`substring()` คืออะไร — ทางเลือกที่คล้าย `slice()` แต่กฎต่างกัน
`substring()` เป็นอีก method ที่ใช้ดึง substring — syntax คล้าย `slice()` มาก (`substring(startIndex, endIndex)`) แต่มีกฎภายในที่ต่างกัน 2 ข้อสำคัญ: 1. **ไม่รู้จัก negative index** — ถ้าใส่ค่าติดลบ `substring()` จะแปลงเป็น `0` ทันที 2. **สลับ argument ให้อัตโนมัติ** — ถ้า `start > end` มันจะสลับให้โดยไม่บอก ทำให้ได้ผลลัพธ์เสมอ (ไม่คืน `""` เหมือน `slice()`)
const text = "hello world";
// substring(0, 5) — เหมือน slice(0, 5)
console.log(text.substring(0, 5)); // "hello"
// substring(6) — ดึงจาก index 6 ถึงจบ
console.log(text.substring(6)); // "world"
// substring() — ไม่ระบุอะไร = copy ทั้ง string
console.log(text.substring()); // "hello world"
// ต้นฉบับไม่เปลี่ยน
console.log(text); // "hello world"const text = "hello world";
// === slice(6, 0) — start > end → คืน ""
console.log(text.slice(6, 0)); // "" ✗
// === substring(6, 0) — start > end → สลับให้เป็น (0, 6)
console.log(text.substring(6, 0)); // "hello" ✓
// === slice(5, 0) — start > end
console.log(text.slice(5, 0)); // "" ✗
// === substring(5, 0)
console.log(text.substring(5, 0)); // "hello" ✓- **`substring(start, end)` — syntax เหมือน `slice`** — ใช้ `start` และ `end` เหมือนกัน
- **ไม่รู้จัก negative index** — `substring(-3)` → `substring(0)` → copy ทั้ง string
- **สลับ argument ให้อัตโนมัติ** — `substring(5, 0)` → `substring(0, 5)` ได้ผลลัพธ์ปกติ
- **substring มีมานาน** — slice มาทีหลังและแนะนำให้ใช้มากกว่า เพราะ predict ได้ดีกว่า
ความแตกต่างระหว่าง `slice()` และ `substring()` — เทียบทีละจุด
ถึงแม้ `slice()` และ `substring()` จะใช้ syntax คล้ายกัน — แต่พฤติกรรมต่างกันใน 3 จุดสำคัญที่ควรรู้ไว้เพื่อเลือกใช้ให้ถูกสถานการณ์
| พฤติกรรม | `slice()` | `substring()` | ตัวอย่าง |
|---|---|---|---|
| รับ negative index | ✅ รองรับ — นับจากท้าย | ❌ ไม่รองรับ — แปลงเป็น `0` | `"abc".slice(-1)` → `"c"` `"abc".substring(-1)` → `"abc"` |
| `start > end` | ❌ คืน `""` (empty) | ✅ สลับ arg ให้อัตโนมัติ | `"abc".slice(2, 0)` → `""` `"abc".substring(2, 0)` → `"ab"` |
| ละ `endIndex` | ดึงถึงจบ string | ดึงถึงจบ string | เหมือนกันทั้งคู่ |
| ละทั้ง `start` และ `end` | copy ทั้ง string | copy ทั้ง string | เหมือนกันทั้งคู่ |
| แนะนำให้ใช้ | ✅ ใช่ — predict ได้ดีกว่า | ⚠️ legacy — มี `slice()` แทนแล้ว |
const text = "JavaScript";
// === 1) Negative index — ความต่างชัดเจนที่สุด
console.log(text.slice(-4)); // "ript" ✓
console.log(text.substring(-4)); // "JavaScript" ✗ (-4 → 0 → copy ทั้ง string)
// === 2) start > end — slice คืน "" / substring สลับให้
console.log(text.slice(5, 0)); // "" ✗
console.log(text.substring(5, 0)); // "JavaS" ✓
// === 3) index ปกติ — เหมือนกัน
console.log(text.slice(0, 4)); // "Java"
console.log(text.substring(0, 4)); // "Java"- **ใช้ `slice()` เป็น default** — predict ได้ตรงไปตรงมา รับ negative index ได้ ไม่มี magic swapping
- **`substring()` ใช้เมื่อต้องสลับ arg อัตโนมัติ** — แต่ในทางปฏิบัติแทบไม่ต้องใช้ เพราะ `slice()` + `Math.min/max` ชัดเจนกว่า
- **`slice()` ใช้ได้ทั้ง string และ array** — เรียนรู้ครั้งเดียวใช้ได้ 2 ที่ (consistency)
- **`substring()` ใช้กับ string ได้อย่างเดียว** — ไม่มีใน array
ใช้ `slice()` ในสถานการณ์จริง — ดึงนามสกุลไฟล์, ชื่อผู้ใช้, และตัวท้าย
`slice()` มี use-case จริงที่ใช้บ่อยมาก — โดยเฉพาะการ extract ข้อมูลจาก string ที่มี pattern แน่นอน โดยใช้ index หรือ negative index เข้าช่วย
// === ดึงนามสกุลไฟล์จากชื่อไฟล์
const filename = "photo.jpg";
// หาตำแหน่งจุดสุดท้าย
const dotIndex = filename.lastIndexOf(".");
// slice จากหลังจุดไปจนจบ
const extension = filename.slice(dotIndex);
console.log(extension); // ".jpg"
// === ลองกับไฟล์อื่น
console.log("document.pdf".slice("document.pdf".indexOf("."))); // ".pdf"
console.log("archive.tar.gz".slice("archive.tar.gz".lastIndexOf("."))); // ".gz"
// === bug ที่ควรระวัง — ถ้าไม่มีจุด
const noExt = "README";
console.log(noExt.slice(noExt.lastIndexOf("."))); // "E" ✗ (lastIndexOf = -1 → slice(-1))
// วิธีแก้: เช็กก่อนว่า lastIndexOf !== -1// === ดึง N ตัวสุดท้าย — เช่น เบอร์โทร, รหัส, เลขบัตร
const code = "ABC-12345";
// slice(-5) — 5 ตัวสุดท้าย
console.log(code.slice(-5)); // "12345"
// === ดึง 3 ตัวสุดท้าย — ทุกรูปแบบ string
console.log("XYZ-999".slice(-3)); // "999"
console.log("TH-001-BKK".slice(-3)); // "BKK"
// === ใช้จริง — แสดงเฉพาะเลข 4 ตัวท้ายของบัตร
const cardNumber = "1234-5678-9012-3456";
console.log("****-" + cardNumber.slice(-4)); // "****-3456"
// === function ช่วย — ดึง n ตัวสุดท้าย
function lastChars(str, n) {
return str.slice(-n);
}
console.log(lastChars("hello", 2)); // "lo"
console.log(lastChars("javascript", 4)); // "ript"- **ดึงนามสกุลไฟล์** — `filename.slice(filename.lastIndexOf("."))`
- **ดึงชื่อผู้ใช้จาก email** — `email.slice(0, email.indexOf("@"))`
- **ดึง N ตัวสุดท้าย** — `str.slice(-n)` ง่ายและตรงไปตรงมา
- **slice() ใช้กับ array ได้ด้วย** — `arr.slice(1, 3)` ดึง element จาก array — เรียนรู้ครั้งเดียวใช้ได้ 2 ที่