ก่อนจะเขียนโค้ดที่ซับซ้อนกว่านี้ เรามาพูดถึงการดีบักกันดีกว่า
การดีบักเป็นกระบวนการค้นหาและแก้ไขข้อผิดพลาดภายในสคริปต์ เบราว์เซอร์สมัยใหม่และสภาพแวดล้อมอื่นๆ ส่วนใหญ่รองรับเครื่องมือแก้ไขจุดบกพร่อง ซึ่งเป็น UI พิเศษในเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ที่ทำให้การดีบักง่ายขึ้นมาก นอกจากนี้ยังช่วยให้ติดตามโค้ดทีละขั้นตอนเพื่อดูว่าเกิดอะไรขึ้น
เราจะใช้ Chrome ที่นี่ เนื่องจากมีฟีเจอร์เพียงพอ เบราว์เซอร์อื่นๆ ส่วนใหญ่จึงมีกระบวนการที่คล้ายกัน
เวอร์ชัน Chrome ของคุณอาจดูแตกต่างออกไปเล็กน้อย แต่ก็ยังควรชัดเจนว่ามีอะไรอยู่บ้าง
เปิดหน้าตัวอย่างใน Chrome
เปิดเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ด้วย F12 (Mac: Cmd + Opt + I )
เลือกแผง Sources
นี่คือสิ่งที่คุณควรเห็นหากคุณทำเป็นครั้งแรก:
ปุ่มสลับ เปิดแท็บพร้อมไฟล์
คลิกแล้วเลือก hello.js
ในมุมมองแบบต้นไม้ นี่คือสิ่งที่ควรปรากฏ:
แผงแหล่งที่มามี 3 ส่วน:
บานหน้าต่าง File Navigator จะแสดงรายการ HTML, JavaScript, CSS และไฟล์อื่นๆ รวมถึงรูปภาพที่แนบมากับเพจ ส่วนขยายของ Chrome อาจปรากฏที่นี่เช่นกัน
บานหน้าต่าง ตัวแก้ไขโค้ด จะแสดงซอร์สโค้ด
บานหน้าต่าง การดีบัก JavaScript มีไว้สำหรับการดีบัก เราจะมาสำรวจกันในเร็วๆ นี้
ตอนนี้คุณสามารถคลิกตัวสลับเดียวกันได้แล้ว อีกครั้งเพื่อซ่อนรายการทรัพยากรและให้พื้นที่โค้ดบางส่วน
หากเรากด Esc คอนโซลจะเปิดขึ้นด้านล่าง เราสามารถพิมพ์คำสั่งที่นั่นแล้วกด Enter เพื่อดำเนินการ
หลังจากดำเนินการคำสั่ง ผลลัพธ์จะแสดงด้านล่าง
ตัวอย่างเช่น ที่นี่ 1+2
ให้ผลลัพธ์เป็น 3
ในขณะที่การเรียกใช้ฟังก์ชัน hello("debugger")
ไม่ส่งคืนสิ่งใด ดังนั้นผลลัพธ์จึง undefined
:
เรามาตรวจสอบสิ่งที่เกิดขึ้นภายในโค้ดของหน้าตัวอย่างกัน ใน hello.js
คลิกที่บรรทัดหมายเลข 4
ใช่ครับ ตรงเลข 4
หลัก ไม่ใช่รหัส
ยินดีด้วย! คุณได้ตั้งค่าเบรกพอยต์แล้ว กรุณาคลิกที่หมายเลขสำหรับบรรทัดที่ 8
ด้วย
ควรมีลักษณะดังนี้ (สีน้ำเงินคือตำแหน่งที่คุณควรคลิก):
เบรกพอยต์ คือจุดของโค้ดที่ตัวดีบักเกอร์จะหยุดการทำงานของ JavaScript ชั่วคราวโดยอัตโนมัติ
ในขณะที่โค้ดถูกหยุดชั่วคราว เราสามารถตรวจสอบตัวแปรปัจจุบัน รันคำสั่งในคอนโซล ฯลฯ กล่าวอีกนัยหนึ่ง เราสามารถดีบักมันได้
เราสามารถค้นหารายการเบรกพอยท์ได้ในแผงด้านขวาเสมอ ซึ่งจะมีประโยชน์เมื่อเรามีจุดพักจำนวนมากในไฟล์ต่างๆ ช่วยให้เราสามารถ:
ข้ามไปยังเบรกพอยต์ในโค้ดอย่างรวดเร็ว (โดยคลิกที่มันในแผงด้านขวา)
ปิดใช้งานเบรกพอยต์ชั่วคราวโดยยกเลิกการเลือก
ลบเบรกพอยต์โดยคลิกขวาแล้วเลือกลบ
…และอื่นๆ
จุดพักแบบมีเงื่อนไข
คลิกขวา ที่หมายเลขบรรทัดเพื่อสร้างจุดพัก แบบมีเงื่อนไข มันจะทริกเกอร์เฉพาะเมื่อนิพจน์ที่กำหนดซึ่งคุณควรระบุเมื่อคุณสร้างนั้นเป็นความจริงเท่านั้น
ซึ่งมีประโยชน์เมื่อเราต้องการหยุดเฉพาะค่าตัวแปรบางตัวหรือพารามิเตอร์ฟังก์ชันบางตัวเท่านั้น
นอกจากนี้เรายังสามารถหยุดโค้ดชั่วคราวได้โดยใช้คำสั่ง debugger
ในนั้น เช่นนี้
ฟังก์ชั่นสวัสดี (ชื่อ) { ให้วลี = `สวัสดี ${name}!`; ดีบักเกอร์; // <-- ดีบักเกอร์หยุดที่นี่ พูด(วลี); -
คำสั่งดังกล่าวจะทำงานเฉพาะเมื่อเครื่องมือการพัฒนาเปิดอยู่เท่านั้น ไม่เช่นนั้นเบราว์เซอร์จะเพิกเฉยต่อคำสั่งนั้น
ในตัวอย่างของเรา hello()
จะถูกเรียกระหว่างการโหลดเพจ ดังนั้นวิธีที่ง่ายที่สุดในการเปิดใช้งานดีบักเกอร์ (หลังจากที่เราตั้งค่าเบรกพอยท์แล้ว) ก็คือการโหลดเพจซ้ำ ลองกด F5 (Windows, Linux) หรือ Cmd + R (Mac)
เมื่อตั้งค่าเบรกพอยต์แล้ว การดำเนินการจะหยุดที่บรรทัดที่ 4:
โปรดเปิดเมนูแบบเลื่อนลงข้อมูลทางด้านขวา (มีป้ายกำกับด้วยลูกศร) อนุญาตให้คุณตรวจสอบสถานะรหัสปัจจุบัน:
Watch
– แสดงค่าปัจจุบันสำหรับนิพจน์ใดๆ
คุณสามารถคลิกเครื่องหมายบวก +
และป้อนนิพจน์ได้ ดีบักเกอร์จะแสดงค่าของมัน และคำนวณใหม่โดยอัตโนมัติในกระบวนการดำเนินการ
Call Stack
– แสดงสายโซ่การโทรที่ซ้อนกัน
ขณะนี้ดีบักเกอร์อยู่ในการเรียก hello()
ซึ่งถูกเรียกโดยสคริปต์ใน index.html
(ไม่มีฟังก์ชันอยู่ที่นั่น ดังนั้นจึงเรียกว่า "ไม่ระบุชื่อ")
หากคุณคลิกที่รายการสแต็ก (เช่น "ไม่ระบุชื่อ") ดีบักเกอร์จะข้ามไปยังโค้ดที่เกี่ยวข้อง และตัวแปรทั้งหมดก็สามารถตรวจสอบได้เช่นกัน
Scope
– ตัวแปรปัจจุบัน
Local
แสดงตัวแปรฟังก์ชันในเครื่อง คุณยังสามารถดูค่าที่เน้นไว้เหนือแหล่งที่มาได้อีกด้วย
Global
มีตัวแปรโกลบอล (ไม่มีฟังก์ชันใด ๆ )
มีคีย์เวิร์ด this
อยู่ด้วยซึ่งเรายังไม่ได้ศึกษา แต่เราจะทำสิ่งนั้นเร็วๆ นี้
ตอนนี้ได้เวลา ติดตาม สคริปต์แล้ว
มีปุ่มอยู่ที่ด้านบนของแผงด้านขวา มามีส่วนร่วมกันเถอะ
– “ดำเนินการต่อ”: ดำเนินการดำเนินการต่อไป, ปุ่มลัด F8 .
ดำเนินการต่อ หากไม่มีจุดพักเพิ่มเติม การดำเนินการจะดำเนินต่อไปและดีบักเกอร์จะสูญเสียการควบคุม
นี่คือสิ่งที่เราสามารถเห็นได้หลังจากคลิก:
การดำเนินการกลับมาทำงานต่อแล้ว ถึงจุดพักอื่นภายใน say()
และหยุดชั่วคราวที่นั่น ดูที่ “Call Stack” ทางด้านขวา มันเพิ่มขึ้นอีกหนึ่งสาย เราอยู่ข้างใน say()
ตอนนี้
– “ขั้นตอน”: เรียกใช้คำสั่งถัดไป ปุ่มลัด F9
เรียกใช้คำสั่งถัดไป หากเราคลิกตอนนี้ ระบบจะแสดง alert
การคลิกที่นี่ครั้งแล้วครั้งเล่าจะเป็นการดูคำสั่งสคริปต์ทั้งหมดทีละรายการ
– “ก้าวข้าม”: เรียกใช้คำสั่งถัดไป แต่ อย่าเข้าสู่ฟังก์ชัน ปุ่มลัด F10
คล้ายกับคำสั่ง “Step” ก่อนหน้า แต่ทำงานแตกต่างออกไปหากคำสั่งถัดไปเป็นการเรียกใช้ฟังก์ชัน (ไม่ใช่คำสั่งในตัว เช่น alert
แต่เป็นฟังก์ชันของเราเอง)
หากเราเปรียบเทียบคำสั่งเหล่านั้น คำสั่ง “Step” จะเข้าสู่การเรียกใช้ฟังก์ชันที่ซ้อนกันและหยุดการดำเนินการที่บรรทัดแรกชั่วคราว ในขณะที่ “Step over” จะดำเนินการเรียกใช้ฟังก์ชันที่ซ้อนกันให้เรามองไม่เห็น โดยข้ามฟังก์ชันภายใน
การดำเนินการจะหยุดชั่วคราวทันทีหลังจากการเรียกใช้ฟังก์ชันนั้น
เป็นเรื่องที่ดีถ้าเราไม่สนใจที่จะเห็นว่าเกิดอะไรขึ้นในการเรียกใช้ฟังก์ชัน
– “ก้าวเข้าสู่”, ปุ่มลัด F11 .
ซึ่งคล้ายกับ "ขั้นตอน" แต่มีพฤติกรรมแตกต่างออกไปในกรณีของการเรียกใช้ฟังก์ชันแบบอะซิงโครนัส หากคุณเพิ่งเริ่มเรียนรู้ JavaScript คุณก็สามารถเพิกเฉยต่อความแตกต่างได้ เนื่องจากเรายังไม่มีการโทรแบบอะซิงโครนัส
ในอนาคต โปรดทราบว่าคำสั่ง "ขั้นตอน" จะละเว้นการดำเนินการแบบอะซิงก์ เช่น setTimeout
(การเรียกใช้ฟังก์ชันตามกำหนดเวลา) ซึ่งจะดำเนินการในภายหลัง “ก้าวเข้าสู่” จะเข้าสู่โค้ดของพวกเขา โดยรอพวกเขาหากจำเป็น ดูคู่มือ DevTools สำหรับรายละเอียดเพิ่มเติม
– “Step out”: ดำเนินการต่อไปจนกระทั่งสิ้นสุดฟังก์ชันปัจจุบัน ปุ่มลัด Shift + F11
ดำเนินการดำเนินการต่อไปและหยุดที่บรรทัดสุดท้ายของฟังก์ชันปัจจุบัน มีประโยชน์เมื่อเราป้อนสายที่ซ้อนกันโดยไม่ตั้งใจโดยใช้ แต่มันไม่ได้สนใจเราและเราต้องการที่จะดำเนินการยุติมันต่อไปโดยเร็วที่สุด
– เปิด/ปิดเบรกพอยต์ทั้งหมด
ปุ่มนั้นจะไม่ย้ายการดำเนินการ เพียงเปิด/ปิดมวลสำหรับเบรกพอยต์
– เปิด/ปิดการหยุดชั่วคราวอัตโนมัติในกรณีที่เกิดข้อผิดพลาด
เมื่อเปิดใช้งาน หากเครื่องมือสำหรับนักพัฒนาเปิดอยู่ ข้อผิดพลาดระหว่างการเรียกใช้สคริปต์จะหยุดชั่วคราวโดยอัตโนมัติ จากนั้นเราสามารถวิเคราะห์ตัวแปรในตัวดีบักเกอร์เพื่อดูว่ามีอะไรผิดพลาด ดังนั้นหากสคริปต์ของเราตายโดยมีข้อผิดพลาด เราสามารถเปิดตัวดีบักเกอร์ เปิดใช้งานตัวเลือกนี้ และโหลดหน้าเว็บใหม่เพื่อดูว่าสคริปต์นั้นอยู่ที่ใดและบริบทในขณะนั้นเป็นอย่างไร
ดำเนินการต่อที่นี่
คลิกขวาที่บรรทัดโค้ดจะเปิดเมนูบริบทพร้อมตัวเลือกที่ดีที่เรียกว่า "ดำเนินการต่อที่นี่"
มีประโยชน์เมื่อเราต้องการย้ายหลายขั้นตอนไปข้างหน้าไปยังเส้น แต่เราขี้เกียจเกินไปที่จะกำหนดเบรกพอยต์
หากต้องการส่งออกบางสิ่งไปยังคอนโซลจากโค้ดของเรา มีฟังก์ชัน console.log
ตัวอย่างเช่น สิ่งนี้จะส่งออกค่าจาก 0
ถึง 4
ไปยังคอนโซล:
// เปิดคอนโซลเพื่อดู สำหรับ (ให้ i = 0; i <5; i++) { console.log("ค่า", i); -
ผู้ใช้ทั่วไปจะไม่เห็นผลลัพธ์นั้น แต่อยู่ในคอนโซล หากต้องการดู ให้เปิดแผงคอนโซลของเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์หรือกด Esc ขณะที่อยู่ในแผงอื่น ซึ่งจะเปิดคอนโซลที่ด้านล่าง
หากเรามีการเข้าสู่ระบบเพียงพอในโค้ดของเรา เราจะสามารถเห็นสิ่งที่เกิดขึ้นจากบันทึก โดยไม่ต้องใช้ดีบักเกอร์
ดังที่เราเห็นแล้วว่า มีสามวิธีหลักในการหยุดสคริปต์ชั่วคราว:
เบรกพอยต์
คำสั่ง debugger
เกิดข้อผิดพลาด (หากเครื่องมือ dev เปิดอยู่และปุ่ม คือ "เปิด")
เมื่อหยุดชั่วคราว เราสามารถดีบักได้: ตรวจสอบตัวแปรและติดตามโค้ดเพื่อดูว่าการดำเนินการผิดพลาดตรงไหน
มีตัวเลือกมากมายในเครื่องมือสำหรับนักพัฒนามากกว่าที่กล่าวถึงในที่นี้ คู่มือฉบับเต็มอยู่ที่https://developers.google.com/web/tools/chrome-devtools
ข้อมูลจากบทนี้เพียงพอที่จะเริ่มต้นการแก้ไขข้อบกพร่อง แต่ในภายหลัง โดยเฉพาะอย่างยิ่งหากคุณใช้เบราว์เซอร์เป็นจำนวนมาก โปรดไปที่นั่นและดูความสามารถขั้นสูงเพิ่มเติมของเครื่องมือสำหรับนักพัฒนา
โอ้ และคุณยังสามารถคลิกที่เครื่องมือ dev ต่างๆ และดูว่ามีอะไรปรากฏขึ้นบ้าง นั่นอาจเป็นเส้นทางที่เร็วที่สุดในการเรียนรู้เครื่องมือ dev อย่าลืมคลิกขวาและเมนูตามบริบท!