5 ข้อผิดพลาดมือใหม่ JavaScript ที่ควรเลิกทำทันที เพื่อโค้ดที่สะอาดขึ้น

10 นาที 14 views บันทึกเป็น PDF
5 ข้อผิดพลาดมือใหม่ JavaScript ที่ควรเลิกทำทันที เพื่อโค้ดที่สะอาดขึ้น

มือใหม่หัดเขียน JavaScript มักเจอบั๊กจากเรื่องง่ายๆ มาดู 5 ข้อผิดพลาดที่พบบ่อย เช่น การใช้ == หรือ var พร้อมวิธีแก้ไขให้โค้ดของคุณดูโปรและทำงานได้แม่นยำขึ้น

เปรียบเทียบค่าแบบหลวมๆ กับแบบเข้มงวด

เวลาเราเขียนโปรแกรม เราต้องมีการเปรียบเทียบค่าอยู่เสมอ เช่น เช็กว่าผู้ใช้กรอกรหัสผ่านตรงกับที่ตั้งไว้ไหม มือใหม่มักจะใช้เครื่องหมาย == (Double Equals) เพราะดูใช้ง่ายและคุ้นตา แต่นี่คือกับดักที่ทำให้เกิดบั๊ก (Bug - ข้อผิดพลาดในโปรแกรม) ได้ง่ายที่สุด เพราะมันเป็นการเปรียบเทียบแบบหลวมๆ ที่ยอมให้ค่าคนละชนิดเท่ากันได้

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

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

// แบบที่ผิด: การเปรียบเทียบแบบหลวม
console.log(0 == "0"); // ผลลัพธ์คือ true เพราะแปลงเลข 0 เป็นข้อความก่อนเทียบ

// แบบที่ถูก: การเปรียบเทียบแบบเข้มงวด
console.log(0 === "0"); // ผลลัพธ์คือ false เพราะชนิดข้อมูลไม่เหมือนกัน

ในตัวอย่างแรก บรรทัดแรกใช้ == ซึ่งทำให้ JavaScript แปลงเลข 0 ให้เป็นข้อความ "0" ก่อนเทียบ ทำให้ค่าเท่ากัน ส่วนบรรทัดที่สองใช้ === เพื่อเช็กทั้งค่าและประเภทข้อมูล ซึ่งเลข 0 เป็นประเภทตัวเลข (Number) ส่วน "0" เป็นข้อความ (String) ผลลัพธ์จึงออกมาเป็นเท็จอย่างที่ควรจะเป็น

ความสับสนระหว่าง var, let และ const

มือใหม่มักจะใช้ var ในการประกาศตัวแปร (Variable - ที่เก็บข้อมูลชั่วคราว) อยู่เสมอ เพราะเห็นคนอื่นใช้ในบทเรียนเก่าๆ แต่ในปัจจุบัน var ถือเป็นวิธีที่ไม่แนะนำแล้ว เพราะมันมีปัญหาเรื่องขอบเขตการใช้งานที่กว้างเกินไปจนคุมได้ยาก และอาจถูกเขียนทับค่าเดิมโดยไม่ตั้งใจ

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

การฝึกนิสัยใช้ const ให้มากที่สุดและใช้ let เมื่อจำเป็น จะช่วยให้โค้ดของคุณอ่านง่ายขึ้นมาก เพราะเพื่อนร่วมงานหรือตัวคุณเองในอนาคตจะรู้ทันทีว่าตัวแปรไหนห้ามเปลี่ยนค่า การเลิกใช้ var จะช่วยลดปัญหาบั๊กที่เกิดจากการประกาศตัวแปรซ้ำซ้อนโดยไม่รู้ตัวได้ดีที่สุด

// การใช้ var ที่อาจเกิดปัญหา
var name = "Alice";
var name = "Bob"; // ไม่มีข้อผิดพลาดแจ้งเตือน ค่าโดนทับเฉยๆ

// การใช้ let และ const ที่ปลอดภัยกว่า
const age = 25; // ค่านี้คงที่ตลอดไป
let score = 0; // ค่านี้เปลี่ยนได้ในอนาคต

บรรทัดที่ใช้ var เราสามารถประกาศชื่อตัวแปรซ้ำได้โดยโปรแกรมไม่เตือนอะไรเลย ซึ่งเป็นเรื่องอันตรายมาก ส่วน const จะล็อกค่าไว้ไม่ให้เปลี่ยน และ let จะยอมให้เปลี่ยนค่าได้แต่ห้ามประกาศชื่อซ้ำในบล็อกเดียวกัน ผลลัพธ์คือโปรแกรมจะฟ้องทันทีหากเราทำผิดกฎ ช่วยให้เราแก้บั๊กได้ตั้งแต่ตอนเขียน

การใช้งาน async และ await ให้ถูกจังหวะ

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

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

หัวใจสำคัญคือต้องใส่คำว่า async ไว้หน้าฟังก์ชัน (Function - ชุดคำสั่งที่รวมกันไว้ทำงานเฉพาะอย่าง) เพื่อบอกให้โปรแกรมรู้ว่าข้างในนี้มีการทำงานที่ต้องรอเวลา และใช้ await นำหน้าคำสั่งดึงข้อมูลเสมอ วิธีนี้จะทำให้โค้ดของคุณทำงานตามลำดับที่ถูกต้องและไม่เกิดข้อผิดพลาดตอนนำข้อมูลไปแสดงผล

// แบบที่ผิด: ไม่รอข้อมูล
function getData() {
  const data = fetch("https://api.example.com");
  console.log(data); // จะได้แค่สถานะ Promise (สัญญาว่าจะส่งข้อมูลมา) ไม่ใช่ตัวข้อมูลจริง
}

// แบบที่ถูก: ใช้ await เพื่อรอข้อมูล
async function getData() {
  const response = await fetch("https://api.example.com");
  const data = await response.json();
  console.log(data); // ได้ข้อมูลจริงออกมาแล้ว
}

ในแบบที่ผิด โปรแกรมจะข้ามไปบรรทัด console.log ทันทีทั้งที่ข้อมูลยังโหลดไม่เสร็จ ส่วนแบบที่ถูก เราใช้ await เพื่อหยุดบรรทัดนั้นไว้จนกว่า fetch จะโหลดข้อมูลเสร็จสมบูรณ์ ผลลัพธ์คือเราจะได้ข้อมูลในรูปแบบ JSON (รูปแบบการแลกเปลี่ยนข้อมูล) มาใช้งานจริงได้ทันที

ความเข้าใจเรื่อง Hoisting ที่มักทำให้สับสน

Hoisting (การยกประกาศขึ้นไปบนสุด) คือพฤติกรรมแปลกๆ ของ JavaScript ที่มักจะย้ายการประกาศตัวแปรขึ้นไปไว้บนสุดของขอบเขตการทำงานโดยอัตโนมัติ มือใหม่อาจจะงงว่าทำไมเรียกใช้ตัวแปรได้ทั้งที่ยังไม่ได้ประกาศบรรทัดก่อนหน้า ซึ่งความเข้าใจผิดตรงนี้อาจนำไปสู่บั๊กที่หาต้นตอได้ยาก

ลองนึกภาพว่ามีคนแอบหยิบชื่อคุณไปใส่ในรายชื่อผู้เข้าแข่งขันก่อนที่คุณจะเดินเข้างานจริงๆ ถ้าคุณใช้ var โปรแกรมจะอนุญาตให้คุณเรียกใช้ชื่อนั้นได้ก่อนประกาศจริง แต่ค่าจะเป็น undefined (ค่าที่ยังไม่ได้กำหนด) ซึ่งสร้างความสับสนว่าตกลงตัวแปรมีค่าหรือไม่มีกันแน่

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

// ปัญหาจาก var
console.log(a); // ได้ค่า undefined
var a = 5;

// ความปลอดภัยจาก let
console.log(b); // เกิดข้อผิดพลาดทันที (ดีแล้ว!)
let b = 5;

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

การคัดลอกข้อมูลแบบผิดวิธี

ใน JavaScript เวลาเราคัดลอก Array (รายการข้อมูล) หรือ Object (กลุ่มข้อมูล) มือใหม่มักจะใช้เครื่องหมายเท่ากับธรรมดา ซึ่งจริงๆ แล้วมันไม่ใช่การคัดลอกค่า แต่เป็นการอ้างอิงถึงที่อยู่ของข้อมูลเดิม ถ้าเราไปแก้ไขข้อมูลในตัวแปรใหม่ ข้อมูลตัวเดิมก็จะเปลี่ยนตามไปด้วยโดยไม่รู้ตัว

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

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

// แบบที่ผิด: การอ้างอิงที่อยู่เดิม
const original = [1, 2, 3];
const copy = original;
copy.push(4);
console.log(original); // ค่าเดิมเปลี่ยนไปด้วย เป็น [1, 2, 3, 4]

// แบบที่ถูก: การสร้างสำเนาใหม่
const properCopy = [...original];
properCopy.push(5);
console.log(original); // ค่าเดิมยังคงเป็น [1, 2, 3, 4]

บรรทัดที่ใช้ copy = original เป็นเพียงการชี้ไปที่ข้อมูลเดียวกัน การแก้ไขตัวหนึ่งจึงกระทบอีกตัว ส่วน [...original] คือการแกะค่าออกมาใส่ในกล่องใบใหม่ที่แยกจากกันโดยสิ้นเชิง ผลลัพธ์คือ original จะไม่ถูกแก้ไขเมื่อเราเพิ่มข้อมูลเข้าไปใน properCopy

สรุปบทเรียนเพื่อการเป็นโปรแกรมเมอร์ที่ดี

การเรียนรู้ JavaScript ไม่ใช่แค่การจำคำสั่งให้ได้ แต่คือการเข้าใจพฤติกรรมของภาษาเพื่อลดความผิดพลาดในการทำงานจริง จากทั้ง 5 ข้อที่กล่าวมา ไม่ว่าจะเป็นการเปรียบเทียบค่า การจัดการตัวแปร หรือการคัดลอกข้อมูล หากคุณฝึกฝนจนเป็นนิสัยตั้งแต่วันนี้ คุณจะเขียนโค้ดที่สะอาดและมีบั๊กน้อยลงอย่างแน่นอน

ลองนำแนวทางเหล่านี้ไปใช้กับโปรเจกต์ (Project - งานที่สร้างขึ้นเพื่อฝึกฝน) เล็กๆ ของคุณดู เช่น การทำแอปรายการสิ่งที่ต้องทำ (To-do List) แทนที่จะใช้ var ให้ลองใช้ const และ let ให้ถูกที่ หรือลองใช้ === แทน == ทุกครั้งที่เขียนเงื่อนไขตรวจสอบค่า

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


ที่มา: 5 Common JavaScript Mistakes Beginners Make (And How to Fix Them) — DEV Community

แชร์บทความ

Facebook X LINE

บทความที่เกี่ยวข้อง

จัดการเซิร์ฟเวอร์ผ่าน VS Code ให้ง่ายขึ้นด้วย Easy SSH พร้อมฟีเจอร์โหลดไฟล์ผ่านคลิกเดียว

จัดการเซิร์ฟเวอร์ผ่าน VS Code ให้ง่ายขึ้นด้วย Easy SSH พร้อมฟีเจอร์โหลดไฟล์ผ่านคลิกเดียว

เบื่อไหมที่ต้องสลับหน้าจอไปมาเพื่อจัดการเซิร์ฟเวอร์? มาลองใช้ Easy SSH ปลั๊กอิน VS Code ที่ช่วยให้คุณรีโมทผ่าน Terminal ได้สะดวก แถมโหลดไฟล์ได้ง่ายแค่กด Ctrl+click

ที่มา: DEV Community

2 hours ago 11 นาที
2 views
วิธีดึงข้อมูลราคาจาก Google Hotels ด้วย API สำหรับนักพัฒนา

วิธีดึงข้อมูลราคาจาก Google Hotels ด้วย API สำหรับนักพัฒนา

อยากทำแอปท่องเที่ยวแต่ดึงข้อมูลราคาจาก Google Hotels ไม่ได้? มาดูวิธีใช้ Apify Actor ช่วยดึงข้อมูลแบบอัตโนมัติด้วย Python ง่ายๆ ไม่ต้องกลัวเว็บพัง

ที่มา: DEV Community

6 hours ago 8 นาที
4 views
วิธีเช็กความพร้อมโปรเจกต์ก่อนปล่อยงานจริงด้วย ReleaseReady

วิธีเช็กความพร้อมโปรเจกต์ก่อนปล่อยงานจริงด้วย ReleaseReady

เคยไหม? โค้ดรันได้ในเครื่องแต่พอปล่อยจริงกลับพัง! มาดูวิธีตรวจสอบความพร้อมของโปรเจกต์ก่อนอัปขึ้น GitHub ด้วยเครื่องมือ ReleaseReady กัน

ที่มา: DEV Community

10 hours ago 9 นาที
5 views