Rumah > Artikel > hujung hadapan web > Perjalanan untuk meningkatkan penyahpepijatan kontemporari: Bahagian 2
Dalam Bahagian 1, kami belajar cara menulis dan melaksanakan JavaScript menggunakan DevTools. Dalam Bahagian 2, kami akan membincangkan cara menyahpepijat JavaScript dan menggunakan aliran kerja untuk menyelesaikan ralat JavaScript dan mendiagnosis isu dengan lebih cekap.
Anda boleh menggunakan kata kunci penyahpepijat terus dalam kod untuk memanggil fungsi penyahpepijatan masa jalan JavaScript (jika ada). Menambah kata kunci debugger
pada kod anda mempunyai kesan yang sama seperti menetapkan titik putus secara manual melalui UI DevTools. Dalam Chrome, kata kunci debugger
tidak mempunyai kesan apabila DevTools ditutup. debugger
的效果与通过 DevTools UI 手动设置断点的效果相同。在 Chrome 中,当 DevTools 关闭时,debugger
关键字不起作用。
调试器控件提供对调试流程的细粒度控制。在断点处暂停时使用它们可以有效地浏览 JavaScript 代码。本节中列出的每个调试器控件都对应于 DevTools 中的一个按钮,您可以在断点处暂停时选择该按钮。
离开当前断点并正常恢复代码执行。这不会影响其他尚未暂停的断点。
当当前暂停的断点没有帮助并且您希望代码恢复正常执行时,请使用 Continue
。
逐行执行代码(每次单击一行),直到到达函数调用为止。此时,函数调用已“跳过”,并且您不会单步执行该特定函数调用。
当您尝试解决的问题仅限于当前函数且无需查看外部函数调用时,请使用 Step Over
。
与 Step Over
类似,不同之处在于在这种情况下,您可以通过转到外部函数调用的第一行来导航到外部函数调用。
当您对逐行执行以及任何外部函数调用感兴趣时,请使用 Step Into
。
当您单步执行函数时,Step Out
将继续执行函数代码的其余部分,但不会进行调试。
当您对当前函数的其余部分不感兴趣并希望在其外部继续调试时,请使用 Step Out
。
在断点处暂停时,调用堆栈处于活动状态。导致当前暂停断点的执行路径显示在调用堆栈中,顶部调用是最近的调用。
堆栈中的每个调用都包含:
单击堆栈中的任何调用即可导航到源代码中的相应位置,并突出显示相关行。要将堆栈跟踪复制到剪贴板,请右键单击某个调用,然后选择复制堆栈跟踪。在调用堆栈上下文菜单中,您还可以选择重新启动框架。
考虑以下用例:调试器在点击事件处理程序触发的回调函数中途暂停,并且您正在尝试调试为什么 target
的检索似乎未按预期工作。
您看到尝试访问目标属性作为 this
关键字的一部分,但您随后回想起它是作为参数传递给回调函数的事件对象的属性部分。
您可以使用实时编辑重写该函数,以验证您的更改是否有效,并将新的 JavaScript 注入到 V8 引擎中。
当您为滚动等事件编写事件处理程序时,您可以首先使用 console.log
来查看传递的参数(事件对象)是什么样子。完成此操作的快速提示是使用 monitorEvents
快捷方式。将以下代码粘贴到控制台面板中,然后滚动页面:
monitorEvents(window, "resize");
请注意,事件对象已记录到控制台以供检查。
当您希望调试器在函数执行期间暂停在函数的第一行时,可以执行以下任一操作:
另一种技术是执行 debug(fn)
,它是命令行 API 的一部分。该函数将您希望调试的函数作为其参数,并将在该函数执行的第一行处中断。
当以任何方式(读取或写入)访问您感兴趣的对象的属性时,此技术使您能够暂停调试器。要在读取或写入对象的属性时中断,请执行以下命令(通过控制台面板或代码段):
Object.defineProperty(document.body, 'scrollTop', { get: function () { debugger; }, set: function (val) { debugger; } });
这会将 getter 和 setter 应用于 document.body
对象的 scrollTop
属性。在自定义 getter 和 setter 中,存在调试器语句。您还可以使用 Object.observe
Teruskan
apabila titik putus yang sedang dijeda tidak membantu dan anda mahu kod anda menyambung semula pelaksanaan biasa. 🎜
Step Over
apabila masalah yang anda cuba selesaikan terhad kepada fungsi semasa dan tidak memerlukan melihat panggilan fungsi luaran. 🎜
Step Over
, kecuali dalam kes ini anda boleh menavigasi ke panggilan fungsi luaran dengan pergi ke baris pertama panggilan fungsi luaran. 🎜
🎜Gunakan Step In
apabila anda berminat dengan pelaksanaan baris demi baris dan sebarang panggilan fungsi luaran. 🎜
Step Out
akan terus melaksanakan kod fungsi yang lain, tetapi tidak akan menyahpepijatnya. 🎜
🎜Gunakan Langkah Keluar
apabila anda tidak berminat dengan fungsi semasa yang lain dan ingin meneruskan penyahpepijatan di luarnya. 🎜
🎜Timbunan panggilan🎜
🎜Semasa berhenti seketika pada titik putus, timbunan panggilan aktif. Laluan pelaksanaan yang menuju ke titik putus jeda semasa ditunjukkan dalam timbunan panggilan, dengan panggilan teratas ialah panggilan terbaharu. 🎜
🎜Setiap panggilan dalam timbunan mengandungi: 🎜
console.log
dahulu untuk melihat rupa parameter yang diluluskan (objek acara). Petua pantas untuk mencapainya ialah menggunakan pintasan monitorEvents
. Tampalkan kod berikut ke dalam Panel Konsol dan tatal halaman: 🎜
var watchMe = {}; Object.observe(watchMe, function() { debugger; });🎜Sila ambil perhatian bahawa objek acara dilog masuk ke konsol untuk diperiksa. 🎜 🎜Nyahpepijat🎜 🎜Apabila anda mahu penyahpepijat menjeda pada baris pertama fungsi semasa pelaksanaannya, anda boleh melakukan salah satu daripada yang berikut: 🎜
debug(fn)
yang merupakan sebahagian daripada API baris arahan. Fungsi ini mengambil sebagai hujahnya fungsi yang anda ingin nyahpepijat dan akan pecah pada baris pertama pelaksanaan fungsi itu. 🎜
🎜Memecahkan akses harta benda🎜
🎜Teknik ini membolehkan anda menjeda penyahpepijat apabila sifat objek yang anda minati diakses dalam apa jua cara (baca atau tulis). Untuk memecahkan semasa membaca atau menulis sifat objek, laksanakan arahan berikut (melalui Panel Konsol atau Coretan Kod): 🎜🎜
function a() { return b(); } function b() { return c(); } function c() { console.trace('The Trace'); return 42; } a();🎜Ini akan menggunakan getter dan setter pada harta
scrollTop
objek document.body
. Dalam getter dan setter tersuai, terdapat pernyataan penyahpepijat. Anda juga boleh menggunakan Object.observe
untuk mengganggu penambahan sifat objek yang ditentukan: 🎜
var watchMe = {}; Object.observe(watchMe, function() { debugger; });
除了调试器关键字之外,要通过 DevTools 设置断点,您可以在行间距内单击要中断的代码行。这种设置断点的方法具有额外的功能:您可以设置一个条件断点,该断点将指示 DevTools 仅当某个表达式计算结果为 true 时才在断点处暂停。例如,您可以设置条件断点,仅在存在错误参数时才暂停。
设置条件断点:
您还可以使用条件断点技术快速插入 console.log
语句作为要计算的表达式。由于 console.log
的计算结果为 undefined
,DevTools 不会暂停,但由于表达式仍在执行,因此您可以通过这种方式检查变量的值。
当调试器在断点处暂停时,您可以使用Escape键在抽屉模式下调出控制台面板。您输入的代码将在与您暂停时相同的上下文中进行计算,这意味着您可以访问作用域内的变量。
监视表达式是一种简化作用域定期检查技术的工具(例如,通过 console.log
)变量。监视表达式是源面板中的一个窗格。您可以使用加号和减号按钮添加或删除监视表达式。需要监视的典型对象是 this
对象;请注意当您未在断点处暂停时它如何引用全局窗口对象。
当您单步执行代码时,监视表达式通常会更新。但是,如果没有,请单击刷新按钮。
考虑以下脚本:
function a() { return b(); } function b() { return c(); } function c() { console.trace('The Trace'); return 42; } a();
共有三个声明的函数。函数 a
调用函数 b
,然后函数 b
调用函数 c
。该脚本通过调用函数 a
来启动链。 console.trace
语句将调用该方法的位置处的堆栈跟踪记录到控制台。使用 console.trace 显示使用 console.trace
的输出。
请注意,函数名称及其调用行显示在跟踪消息中。您可以通过“源代码”面板单击要转到源代码中相应位置的行号。此技术也适用于片段。
调试器提供了多种处理异常的模式:
当您必须调试一个您不太了解的站点时,您可以使用不同的调试技术。在这种方法中,您可以挂钩您认为会触发的事件,并在此类事件发生时请求 DevTools 中断。 “外部>内部”入口点有两类:
您的任务是调试网页,特别是 DOM。节点在页面的生命周期中添加和删除,您需要检查实现此操作的 JavaScript。通过以下步骤设置 DOM 断点:
每次设置 DOM 断点时,您都可以在DOM 断点处轻松打开和关闭它元素面板中的strong>窗格。在此窗格中,列出了您设置的每个断点,您可以通过以下方式与此窗格交互:
描述:当根节点(设置了断点)的树发生更改时,就会发生子树修改。这可以包括添加或删除节点。
用例:DOM 中存在一个空的 div
容器,并且页面加载时会发生 Ajax 请求,该请求会在原始容器中附加一些新节点。在容器上添加子树修改断点,以查看代码中向 DOM 添加新节点的确切位置。
消息示例: 在 子树上暂停 已修改
在 body
上设置的断点,因为其后代 p
已被删除。或者:在 子树上暂停 在 <code class="inline">div#parent
上设置修改的 断点,因为新的子节点已添加到该节点。
说明:当添加、删除或修改节点上的属性名称或值时,会触发属性修改。这包括所有属性,例如 class
、data-*
或 style
。
用例:页面上看似随机的时间点发生了视觉变化,您将其范围缩小到在 body 元素上动态设置的类。您希望调查此动态类添加的原因。
消息示例: 在 在 <code class="inline">p
上设置的属性 Modified 断点处暂停。
描述:节点删除断点在从包含设置断点的父节点中删除节点时触发。
用例:您正在构建一个待办事项列表应用,并希望验证当用户删除待办事项时,它也会从 DOM 中删除。您可以设置节点删除断点来确保发生此行为。
消息示例: 在 节点已删除的 <code class="inline">div#container
上暂停。
在 DevTools 中,您可以启用许多预定义的事件侦听器断点。这些提供属于页面的 JavaScript 的入口点。
考虑一个简单的 about:blank
页面。通过以下步骤在此页面上设置 click
事件侦听器断点:
Mouse
事件侦听器类别。Click
事件侦听器。您现在已经设置了断点。如果您单击该页面,请注意没有任何反应。现在在控制台面板中执行以下 JavaScript 代码。
document.addEventListener('click', console.log.bind(console))
当您为已注册事件侦听器的同一事件设置断点时,调试器会在执行事件侦听器回调的点之前暂停。
您可以为多种类型的事件注册断点,例如计时器、触摸事件等,如下表所列。
活动类别 | 事件示例 |
---|---|
动画 |
请求动画帧、取消动画帧、动画帧触发 |
控制 |
调整大小、滚动、缩放、聚焦、模糊、选择、更改、提交、重置 |
剪贴板 |
复制、剪切、粘贴、复制前、剪切前、粘贴前 |
DOM 突变 |
DOMActivate、DOMFocusIn、DOMFocusOut、DOMAttrModified、DOMCharacterDataModified、DOMNodeInserted、DOMNodeInsertedIntoDocument、DOMNodeRemoved、DOMNodeRemovedFromDocument、DOMSubtreeModified、DOMContentLoaded |
设备 |
设备方向、设备运动 |
拖放 |
dragenter、dragover、dragleave、drop |
键盘 |
按键、按键、按键、输入 |
加载 |
加载、卸载前、卸载、中止、错误、hashchange、popstate |
鼠标 |
单击、dblclick、mousedown、mouseup、mouseover、mousemove、mouseout、mousewheel、wheel |
计时器 |
setTimer、clearTimer、timerFired |
触摸 |
触摸开始、触摸移动、触摸结束、触摸取消 |
WebGL |
webglErrorFired、webglWarningFired |
Teknik "penyahpepijatan luar dalam" boleh berguna apabila anda perlu menyahpepijat tapak web pihak ketiga yang mempunyai fungsi yang rosak, atau walaupun anda ingin tahu tentang cara sesuatu pada halaman berjalan apabila kandungan anda rosak melihat sedang berjalan.
Banyak sambungan Chrome wujud, kebanyakannya meningkatkan fungsi DevTools. Galeri Sambungan DevTools boleh dimuat turun dari Galeri Sambungan DevTools
Untuk pengarang sambungan DevTools, keupayaan prapemprosesan JavaScript ialah topik yang berbaloi untuk dipelajari. Prapemproses boleh memintas kod sumber JavaScript sebelum ia memasuki enjin V8, yang bermaksud kod sumber JavaScript boleh diubah suai oleh DevTools sebelum ia memasuki VM, semuanya daripada sambungan.
Selain keupayaan pemintasan, API prapemprosesan mempunyai akses program untuk memuat semula sumber skrip. Sambungan boleh memuatkan semula sumber JavaScript pada bila-bila masa dalam kitaran hayatnya tanpa memuat semula halaman web asal.
Bahagian ini memperkenalkan beberapa alatan yang menyediakan tahap penyepaduan tertentu antara alat pembangunan Node.js dan Chrome.
DevTools mempunyai dua bahagian:
Sebarang aplikasi boleh berkomunikasi melalui protokol penyahpepijatan jauh dan membenarkan penggunanya menyahpepijat melalui DevTools. Pemeriksa Nod adalah salah satu alat sedemikian. Setelah dipasang, anda boleh menggunakan Node Inspector untuk menjalankan sebarang skrip nod. Alat ini memulakan pelayan web yang mengehoskan bahagian hadapan DevTools. Versi khusus DevTools ini tidak menggunakan bahagian belakang Chrome, sebaliknya menggunakan bahagian belakang Node Inspector sendiri.
Seperti yang anda lihat dalam Pemeriksa Nod, DevTools berhenti seketika pada titik putus. Tindanan panggilan merujuk kepada panggilan yang dilakukan dalam Node.js. Satu-satunya penglibatan penyemak imbas di sini ialah UI DevTools.
Gunakan Node Heapdump untuk mengambil gambar timbunan V8 pada titik tertentu dalam kod anda. Keadaan semasa timbunan V8 adalah bersiri dan output ke fail.
Bandingkan dua petikan timbunan untuk mengetahui objek yang bukan sampah dikumpul. Ini berguna untuk menangkap kebocoran memori.
Itu menyimpulkan siri dua bahagian ini mengenai pengalaman penyahpepijatan moden. Semoga sekarang anda selesa menulis dan menyahpepijat JavaScript dalam Chrome DevTools. Anda sudah biasa dengan aliran kerja yang membantu dengan penyahpepijatan dan anda mengetahui beberapa petua dan kiat untuk bekerja dengan tapak pengeluaran yang anda tidak pernah bekerja dengannya sebelum ini. Lain kali anda perlu nyahpepijat, pastikan anda mencuba beberapa teknik yang anda pelajari di sini.
Terima kasih kerana membaca!
Atas ialah kandungan terperinci Perjalanan untuk meningkatkan penyahpepijatan kontemporari: Bahagian 2. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!