สวัสดีครับทุกคนสำหรับบทความนี้ เราจะมาพูดถึงสิ่งที่พวกเราชาวเดฟจะต้องเจอไม่ว่าจะเป็นมือใหม่หรือเก๋าที่ทำงานเขียนโปรแกรมมาแล้วหลายปีต่างก็ต้องเจอด้วยกันทั้งนั้น นั้นก็คือการแก้ Bug หาว่า Bug ที่เกิดขึ้นมันเกิดขึ้นมาจากตรงไหน แล้วเราจะแก้กันยังไง? โดยเราจะเรียกกระบวนการหาและแก้ Bug นี้ว่า “Debugging”
ก่อนจะไป Debugging มารู้จัก Bug กันก่อน
ส่วน Bug ที่เราพูดถึงกันมันก็คือ ข้อผิดพลาดที่ทำงานโปรแกรมของเราทำงานไม่ถูกต้อง โดย Bug นั้นสามารถเกิดขึ้นได้หลายรูปแบบ เช่น เราสร้างโปรแกรมเครื่องคิดเลข แต่พอเรากดบวกเลขอย่าง 2 กับ 2 โปรแกรมดันให้ผลลัพธ์ออกมาเป็น 5 ซะอย่างงั้น แบบนี้แหละที่เราเรียกว่า Bug ซึ่งพอมันเกิดแบบนี้ เราก็ต้องไปหาว่าทำไมมันถึงทำงานออกมาแบบนี้ เขียนอะไรผิดไว้ตรงไหน และแก้ไขให้มันทำงานถูกต้องยังไง
Bug ที่เจอบ่อยมีแบบไหนบ้าง?
- Syntax Errors: โค้ดไม่สามารถรันได้ เนื่องจากเขียนคำสั่งผิด ไม่ตรงตามไวยากรณ์ของภาษา
- Logical Errors: โปรแกรมรันได้ แต่ผลลัพธ์ไม่ถูกต้อง
- Runtime Errors: ข้อผิดพลาดเกิดขึ้นระหว่างการทำงาน เช่น เราสั่งให้มันหารด้วย 0
- Semantic Errors: โค้ดทำงานได้ตามที่ตั้งใจ แต่ไม่ใช่ตามที่ผู้ใช้ต้องการ
หากยังไม่เห็นภาพเรามาดูตัวอย่างเล็ก ๆ น้อย ๆ กันครับ
ตัวอย่าง Syntax Error
console.log("Hello World); // ลืมปิดเครื่องหมายคำพูด
JavaScriptข้อผิดพลาด: SyntaxError: Unexpected end of input
ตัวอย่าง Logical Error
function add(a, b) {
return a - b; // ควรจะเป็นการบวก แต่เขียนเป็นลบ
}
const result = add(2, 3);
console.log(result); // ควรได้ 5 แต่จะได้ -1
JavaScriptข้อผิดพลาด: การเขียน logic ผิด ทำให้ผลลัพธ์ไม่ถูกต้อง
ตัวอย่าง Runtime Error
function divide(a, b) {
return a / b;
}
const result = divide(10, 0); // แบ่งด้วยศูนย์
JavaScriptข้อผิดพลาด: ผลลัพธ์จะเป็น Infinity ซึ่งไม่ใช่ค่าที่ใช้ได้จริง
เทคนิคและเครื่องมือที่จะช่วยให้การ Debug เป็นเรื่องง่าย
ต่อมาเรามาดูกันดีกว่าเราจะใช้เทคนิคหรือเครื่องมืออะไรในการหาเจ้า bug ในโปรแกรมของเราได้บ้าง
Manual Debugging เป็นท่าพื้นฐานที่คนเขียน JavaScript ต้องเคยใช้ console.log() หรือหากเป็นภาษาอื่น ๆ ก็จะใช้คำสั่งที่แตกต่างออกไปเช่น print() ของ Python อยากตัวอย่างนี้เราสามารถใช้ console.log() เพื่อดูค่าของตัวแปรได้
function calculateTotal(price, taxRate) {
const total = price + (price * taxRate);
console.log(`Price: ${price}, Tax Rate: ${taxRate}, Total: ${total}`); // Debugging ด้วย console.log
return total;
}
calculateTotal(100, 0.05);
JavaScriptต่อมาหากใครใช้พวก Developer Tools เราสามารถใช้ Breakpoints ได้มันจะใช้ในการหยุดโปรแกรมในบรรทัดที่เราต้องการและดูค่าที่อยู่ในตัวแปร ณ ตอนนั้นได้ วิธีใช้งานโดยทั่วไปสามารถทำได้ดังนี้
- เปิด DevTools ใน Chrome โดยกด F12 หรือ Ctrl+Shift+I
- ไปที่แท็บ Sources
- คลิกที่หมายเลขบรรทัดในโค้ดเพื่อวาง breakpoint
ตัวอย่างโค้ด JavaScript สำหรับการสาธิตการตั้ง breakpoint ใน Chrome DevTools
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JavaScript Breakpoint Demo</title>
</head>
<body>
<h1>JavaScript Breakpoint Demo</h1>
<button onclick="calculate()">Calculate</button>
<script>
function calculate() {
let a = 5;
let b = 10;
let result = add(a, b);
console.log("Result: " + result);
}
function add(x, y) {
return x + y;
}
</script>
</body>
</html>
JavaScript- เปิดหน้าเว็บที่มีโค้ดข้างต้นในเบราว์เซอร์ Google Chrome
- กด F12 หรือ Ctrl+Shift+I เพื่อเปิด DevTools
- ไปที่แท็บ Sources
- เปิดไฟล์ HTML ที่แสดงผลอยู่ใน DevTools
- ในส่วนของ JavaScript (<script>), คลิกที่หมายเลขบรรทัดของฟังก์ชัน add(x, y) เพื่อวาง breakpoint
- กดปุ่ม “Calculate” ในหน้าเว็บ
- ตอนนี้ DevTools จะหยุดการทำงานของโค้ดที่บรรทัดที่คุณตั้ง breakpoint คุณสามารถดูค่าของตัวแปร x, y และ result ได้
ต่อมาเป็นเรื่องของการใช้ Linters เช่น ESLint เป็นเครื่องมือที่ช่วยตรวจสอบข้อผิดพลาดที่มักพบได้ง่ายในโค้ดโดยไม่ต้องรันโปรแกรมจริง ตัวอย่างเช่น ESLint สามารถแจ้งเตือนหากลืมใส่ semicolon ใน JavaScript
let name = 'John';
const age = 30
console.log(name, age)
JavaScriptกลยุทธ์สุดเจ๋งที่เราใช้หาบัค
ถามเป็ดด้วยเทคนิค Rubber Duck Debugging ที่เป็นวิธีการอธิบายโค้ดให้ตัวเองฟัง (หรือกับวัตถุที่ไม่มีชีวิต เช่น ตุ๊กตาเป็ด) วิธีนี้จะช่วยให้เรามองเห็นปัญหาที่อาจไม่เห็น เมื่อเราลองคุยกับตัวเองหรืออะไรสักอย่างแบบเงียบ ๆ ตัวอย่างเช่น เจอบัคเราก็เล่าให้เป็ดฟัง ถามกับตัวเองว่าเงื่อนไขทั้งหมดในฟังก์ชันตรงๆ นี้ๆ จัดการไว้ยังไง แล้วมันทำอะไรต่อ หลายครั้งที่เราจะนึกวิธีการแก้ออกจากตรงนี้นี่แหละ
ขอบคุณภาพจาก : https://www.tweaktown.com/news/99672/russia-affiliated-criminals-use-sitting-duck-technique-to-bag-30-000-domains/index.html
หากโค้ดมันใหญ่มีความซับซ้อนมาก ๆ เราสามารถลองแบ่งโค้ดออกเป็นส่วนย่อย แล้วเอาไปลองเช็คดูว่าแต่ละส่วนมันทำงานยังไง มีปัญหาหรือป่าว เราอาจจะเจอปัญหาจากโค้ดที่เราแยกไปแล้ว สามารถกลับมาแก้ไขที่โค้ดหลักได้ ตัวอย่างเช่นโค้ดนี้เราสามารถ ตรวจสอบ step1() และ step2() ทีละส่วนก่อนที่จะรวมผลลัพธ์ทั้งหมดได้
function complexFunction(a, b) {
const part1 = step1(a);
const part2 = step2(b);
const result = combine(part1, part2);
return result;
}
JavaScriptแต่ถ้าเปลี่ยนแล้ว เอากลับไปใส่ของเดิมแล้วพังเป็นโดมิโน โอ้ พระเจ้า เหตุการณ์นี้สิ่งที่เรียกว่า Version Control อย่าง Git ช่วยคุณได้ เราสามารถใช้มันในการย้อนกลับไปในเวอร์ชันที่ปัญหายังไม่เกิดได้ เป็นเหมือนจุดเซฟที่ตายแล้วเกิดใหม่ที่จุดเซฟ ไม่ต้องเริ่มใหม่
ทั้งหมดนี้ก็จะเป็นเทคนิคเล็ก ๆ น้อย ๆ ที่มือใหม่ควรรู้สำหรับการหาบัค แก้ไขบัคที่เกิดขึ้น แอดหวังว่าบทความนี้จะเป็นประโยชน์กับทุกคนนะครับ 🧡