JavaScript
String Methods
slice
เรียนรู้การใช้ slice() ดึง substring จาก string — slice(start, end) โดย start รวม end ไม่รวม, รองรับ negative index นับจากท้าย string, ไม่เปลี่ยน string ต้นฉบับ (immutable) พร้อมการใช้งานจริงในการดึง domain จาก email, ดึงนามสกุลไฟล์, และตัดอักขระหัวท้าย
slice() — ดึง substring จาก string
slice() คือ method สำหรับดึง substring (ข้อความย่อย) ออกจาก string — คืนค่าเป็น string ใหม่ที่ประกอบด้วยตัวอักษรในช่วงที่เรากำหนด syntax: str.slice(start, end?) กฎสำคัญ: - start: index ที่เริ่มดึง (รวม — นับตัวอักษรตำแหน่งนี้ด้วย) - end: index ที่หยุดดึง (ไม่รวม — ตัวอักษรตำแหน่งนี้จะไม่ถูกดึงมาด้วย) - ถ้าไม่ระบุ end — ดึงไปจนจบ string เลย - ตัวแปรต้นฉบับไม่ถูกเปลี่ยนแปลง — string เป็น immutable (เปลี่ยนค่าไม่ได้) slice() จึงคืนค่า string ใหม่เสมอ
slice() ดึง substring จาก index 0 ถึง 4 (ไม่รวม 4)
let text = "JavaScript";
// slice(0, 4) — ดึง index 0,1,2,3 (หยุดก่อน index 4)
console.log(text.slice(0, 4)); // "Java"
// slice(4) — ไม่ระบุ end → ดึงตั้งแต่ index 4 จนจบ
console.log(text.slice(4)); // "Script"
// ตัวแปรต้นฉบับไม่เปลี่ยน
console.log(text); // "JavaScript"- slice(start, end) — ดึง substring จาก start (รวม) ถึง end (ไม่รวม)
- end เป็น optional — ถ้าไม่ระบุ จะดึงไปจนจบ string
- string ต้นฉบับไม่ถูกเปลี่ยนแปลง — immutable — slice() คืนค่า string ใหม่
- slice() ใช้ได้กับทั้ง string และ array (เรียนไปแล้วในบท Arrays)
start และ end — กำหนดช่วงที่จะดึง
start และ end คือ index บน string — ทำงานเหมือนพิกัดบนไม้บรรทัด: - start: ตัวอักษรตำแหน่งนี้รวมเข้าไปในผลลัพธ์ด้วย - end: ตัวอักษรตำแหน่งนี้ไม่รวม — หยุดดึงก่อนถึงตำแหน่งนี้ จำนวนตัวอักษรที่ได้ = end - start ตัวอย่าง: "JavaScript".slice(0, 4) → ดึง index 0,1,2,3 = 4 ตัว (4 - 0 = 4) ถ้าไม่ระบุ start — start จะเป็น 0 (เริ่มจากตัวแรก) ถ้าไม่ระบุ end — end จะเป็น str.length (ไปจนจบ string) และที่สำคัญ — slice() จะคืนค่า "" (string ว่าง) ถ้า start >= end — เพราะไม่มีตัวอักษรให้ดึง
ทดลอง slice ด้วย start และ end แบบต่าง ๆ
let text = "JavaScript";
// 0123456789 ← index
console.log(text.slice(0, 4)); // "Java" — index 0,1,2,3
console.log(text.slice(4, 10)); // "Script" — index 4,5,6,7,8,9
console.log(text.slice(0, 10)); // "JavaScript" — ทั้งหมด
console.log(text.slice(4, 4)); // "" — start === end → ไม่มีอะไรให้ดึง
console.log(text.slice(4, 2)); // "" — start > end → ไม่มีอะไรให้ดึง
// ไม่ระบุ start → เริ่มจาก 0
console.log(text.slice(undefined, 4)); // "Java"
// ไม่ระบุ end → ดึงจนจบ
console.log(text.slice(4)); // "Script"- start: index เริ่มดึง (รวม) — default = 0
- end: index หยุดดึง (ไม่รวม) — default = str.length
- จำนวนตัวอักษรที่ได้ = end - start
- start >= end → คืนค่า "" (string ว่าง) — ไม่มีช่วงให้ดึง
- slice() ไม่ throw error แม้ start หรือ end จะเกินขอบเขต — จะคืนค่า "" แทน
Negative Index — นับจากท้าย string
slice() รองรับ index ติดลบ (negative index) — ค่าติดลบจะถูกนับถอยหลังจากท้าย string - -1: ตัวอักษรสุดท้าย - -2: ตัวอักษรรองสุดท้าย - -str.length: ตัวอักษรแรก (เท่ากับ 0) กฎการแปลง: - ถ้า start ติดลบ → ใช้ str.length + start (เช่น -1 → length - 1 = ตัวสุดท้าย) - ถ้า end ติดลบ → ใช้ str.length + end (เช่น -1 → length - 1 = หยุดก่อนตัวสุดท้าย) นี่คือฟีเจอร์ที่มีประโยชน์มากของ slice() — ใช้ดึง "N ตัวสุดท้าย" หรือ "ทั้งหมดยกเว้น N ตัวสุดท้าย" ได้ง่ายมาก
ใช้ index ติดลบเพื่อนับจากท้าย string
let text = "JavaScript";
// ^ index: -6 ถึง -1
// slice(-6) — ดึง 6 ตัวสุดท้าย
console.log(text.slice(-6)); // "Script"
// slice(0, -1) — ดึงตั้งแต่ต้น ยกเว้นตัวสุดท้าย
console.log(text.slice(0, -1)); // "JavaScrip"
// slice(-6, -1) — ดึงจาก index -6 ถึงก่อน -1
console.log(text.slice(-6, -1)); // "Scrip"
// slice(-3) — ดึง 3 ตัวสุดท้าย
console.log(text.slice(-3)); // "ipt"
// slice(-10, -6) — (-10→0) ถึง (-6→4) = "Java"
console.log(text.slice(-10, -6)); // "Java"
// ตัวต้นฉบับไม่เปลี่ยน
console.log(text); // "JavaScript"- -1 = ตัวสุดท้าย, -2 = รองสุดท้าย, ... ไปเรื่อย ๆ
- slice(-N) = "N ตัวสุดท้าย" — ใช้บ่อยมาก
- slice(0, -N) = "ทั้งหมดยกเว้น N ตัวสุดท้าย"
- slice(-N, -M) = "เริ่มจากตัวที่ N จากท้าย ถึงก่อนตัวที่ M จากท้าย"
- ถ้า start ติดลบแล้วแปลงแล้ว >= end ที่แปลงแล้ว → คืนค่า ""
กรณีพิเศษ — index เกินขอบเขต และ edge cases
slice() ไม่ throw error เมื่อ index เกินขอบเขต — มันจะปรับค่าให้อยู่ในช่วงที่สมเหตุสมผลโดยอัตโนมัติ: 1) start >= str.length — คืนค่า "" (string ว่าง) เพราะไม่มีตัวอักษรให้ดึงตั้งแต่ตำแหน่งนั้น 2) end > str.length — end จะถูกปรับเป็น str.length (คือจบ string) — ไม่ error 3) start ติดลบที่แปลงแล้วน้อยกว่า 0 — จะถูกปรับเป็น 0 (เริ่มจากตัวแรก) 4) end ติดลบที่แปลงแล้วน้อยกว่า 0 — จะคืนค่า "" เพราะช่วงการดึงไม่สมเหตุสมผล 5) ถ้าผลลัพธ์หลังแปลงแล้ว start >= end — คืนค่า "" เสมอ พฤติกรรม "เงียบ" นี้ทำให้ slice() ปลอดภัยในการใช้งาน — ไม่ต้องกังวลว่า index จะหลุดขอบ
ทดสอบกรณี index เกินขอบเขตของ slice()
let text = "Hello";
// 01234
// 1) start >= length → ""
console.log(text.slice(5)); // "" — length=5, เริ่มที่ 5 ไม่มีอะไร
console.log(text.slice(10)); // "" — 10 > length
// 2) end > length → end ถูกปรับเป็น length
console.log(text.slice(0, 100)); // "Hello" — end ถูกตัดเหลือ 5
// 3) start ติดลบที่แปลงแล้ว < 0 → ปรับเป็น 0
console.log(text.slice(-100)); // "Hello" — -100 → 0 (เริ่มต้นเลย)
// 4) end ติดลบที่แปลงแล้ว <= 0 → ""
console.log(text.slice(0, -100)); // "" — -100+5 = -95 → ปรับเป็น 0 → 0 >= 0
// 5) start >= end หลังแปลง → ""
console.log(text.slice(3, -4)); // "" — start=3, end=-4→1 → 3 >= 1
// ตัวต้นฉบับยังเหมือนเดิม
console.log(text); // "Hello"- slice() ไม่ throw error — ปรับค่า index ให้อยู่ในขอบเขตโดยอัตโนมัติ
- start >= str.length → "" — ไม่มีอะไรให้ดึง
- end > str.length → end = str.length — ไม่ error
- start ติดลบที่น้อยกว่า -length → start = 0
- ผลลัพธ์ไม่เคยเป็น null หรือ undefined — เป็น string ว่าง ("") เสมอเมื่อช่วงไม่สมเหตุสมผล
การใช้งานจริง
slice() ใช้งานบ่อยมากเมื่อต้องการแยกส่วนของ string — โดยมักใช้ร่วมกับ indexOf() และ lastIndexOf() เพื่อหาตำแหน่งที่ต้องการก่อน แล้วใช้ slice() ดึงส่วนที่ต้องการ: - ดึง domain จาก email: หา @ ด้วย indexOf() → slice ตั้งแต่หลัง @ - ดึงนามสกุลไฟล์: หา . ตัวสุดท้ายด้วย lastIndexOf() → slice ตั้งแต่หลัง . - ดึง path จาก URL: หา / ตัวสุดท้าย → slice ตั้งแต่หลัง / - ดึงข้อความระหว่าง delimiter: หาตำแหน่งเริ่มและจบด้วย indexOf() → slice(start+1, end)
use case ที่พบบ่อยของ slice()
// 1) ดึง domain จาก email
let email = "user@example.com";
let atIndex = email.indexOf("@");
let domain = email.slice(atIndex + 1); // ตั้งแต่หลัง @ จนจบ
console.log(domain); // "example.com"
// 2) ดึงนามสกุลไฟล์
let filename = "document.manual.pdf";
let dotIndex = filename.lastIndexOf(".");
let extension = filename.slice(dotIndex + 1);
console.log(extension); // "pdf"
// 3) ดึง filename จาก path
let path = "/images/photo.jpg";
let slashIndex = path.lastIndexOf("/");
let name = path.slice(slashIndex + 1);
console.log(name); // "photo.jpg"
// 4) ตัด prefix ที่รู้ความยาว
let phone = "+66812345678";
let withoutPrefix = phone.slice(3); // ตัด "+66" ออก
console.log(withoutPrefix); // "812345678"
// 5) ดึง N ตัวสุดท้าย
let code = "ABC-12345";
let last4 = code.slice(-4);
console.log(last4); // "2345"
// 6) ตัดหัวและท้ายพร้อมกัน
let word = " Thailand ";
let trimmed = word.slice(1, -1);
console.log(trimmed); // "Thailand"- ดึง domain จาก email — indexOf('@') + slice(at+1)
- ดึงนามสกุลไฟล์ — lastIndexOf('.') + slice(dot+1)
- ดึง filename จาก path — lastIndexOf('/') + slice(slash+1)
- ตัด prefix ตายตัว — slice(knownLength)
- ดึง N ตัวสุดท้าย — slice(-N)
- ตัดหัว-ท้าย — slice(1, -1)
ข้อผิดพลาดที่พบบ่อย
มือใหม่มักเจอข้อผิดพลาดเหล่านี้เมื่อใช้ slice():
- ลืมว่า end ไม่รวม — slice(0, 2) ดึง index 0 และ 1 (2 ตัว) ไม่ใช่ 0,1,2 (3 ตัว) — จำนวนตัวอักษร = end - start
- ลืมว่า slice() ไม่เปลี่ยน string ต้นฉบับ — ต้องเก็บผลลัพธ์ใส่ตัวแปรใหม่: let result = str.slice(0, 4) — ไม่ใช่ str.slice(0, 4) เฉย ๆ แล้วคาดหวังว่า str จะเปลี่ยน
- คิดว่า slice() กับ substring() เหมือนกันทุกอย่าง — slice() รองรับ negative index แต่ substring() ไม่รองรับ (จะเรียนในบทถัดไป)
- start > end → ได้ "" — ไม่ error แต่ก็ไม่ใช่ผลลัพธ์ที่คาดหวัง — ตรวจสอบลำดับ start/end เสมอ
- ลืมว่า index เริ่มจาก 0 — ตัวแรกคือ index 0, ตัวที่ N คือ index N-1 — "Hello".slice(0, 1) → "H" ไม่ใช่ "He"
- ใช้ slice() กับค่า null หรือ undefined — จะเกิด TypeError — ต้องตรวจสอบก่อนว่าเป็น string จริง
ข้อผิดพลาดที่พบบ่อยและวิธีแก้ไข
let text = "Hello World";
// ❌ ผิด: ลืมว่า end ไม่รวม
console.log(text.slice(0, 2)); // "He" — ถูกแล้ว (2 ตัว: index 0,1)
// แต่ถ้าคิดว่าจะได้ 0,1,2 = "Hel" — นั่นคือความเข้าใจผิด
// ✅ ถูก: ถ้าต้องการ 3 ตัวแรก ต้องใช้ end = 3
console.log(text.slice(0, 3)); // "Hel"
// ❌ ผิด: คาดหวังว่า slice() จะเปลี่ยนตัวแปรเดิม
text.slice(0, 5); // ทำอะไร? ไม่ทำอะไรเลย — ผลลัพธ์ถูกทิ้ง
console.log(text); // "Hello World" — ไม่เปลี่ยน!
// ✅ ถูก: เก็บผลลัพธ์ในตัวแปรใหม่
let sliced = text.slice(0, 5);
console.log(sliced); // "Hello"
// ❌ ผิด: start > end
console.log(text.slice(6, 0)); // "" — ไม่ใช่ "World Hello"
// ✅ ถูก: start < end
console.log(text.slice(0, 5)); // "Hello"
console.log(text.slice(6, 11)); // "World"สรุป
- slice(start, end?) — ดึง substring จาก start (รวม) ถึง end (ไม่รวม) — คืนค่า string ใหม่
- ไม่ระบุ end → ดึงจนจบ string — slice(4) = ตั้งแต่ index 4 จนจบ
- ไม่ระบุ start → เริ่มจาก 0 — slice(undefined, 4) = slice(0, 4)
- Negative index: -1 = ตัวสุดท้าย, -N = N ตัวจากท้าย — slice(-3) = 3 ตัวสุดท้าย — slice(0, -1) = ทั้งหมดยกเว้นตัวสุดท้าย
- start >= end → คืนค่า "" — จำนวนตัวอักษรที่ได้ = end - start
- string ต้นฉบับไม่เปลี่ยน — immutable — ต้องเก็บผลลัพธ์ในตัวแปรใหม่
- ปลอดภัย — slice() ไม่ throw error เมื่อ index เกินขอบเขต — คืนค่า "" แทน
- ใช้คู่กับ indexOf() / lastIndexOf() เพื่อดึงส่วนของ string แบบ dynamic — เช่น ดึง domain จาก email, ดึงนามสกุลไฟล์
- ใช้ slice() เมื่อต้องการ substring แบบยืดหยุ่น — รองรับ negative index, ไม่ error เมื่อ index หลุด — ใช้ substring() เมื่อต้องการแค่ index บวก (จะเรียนในบทถัดไป)