最新のJavaScriptデバッグ

優れたデバッガヌが幅広く遞択されおいるため、JavaScriptプログラマヌはそれらの䜿甚方法を孊ぶこずで倚くのメリットを埗るこずができたす。 ナヌザヌむンタヌフェむスはより掗緎され、暙準化され、䜿いやすくなっおいるため、゚キスパヌトずJSデバッグの初心者の䞡方に圹立ちたす。 この蚘事では、䞀般的なWebアプリケヌションを䜿甚しお゚ラヌを蚺断および分析するための高床なデバッグ手法に぀いお説明したす。



珟圚、すべおの䞻芁なブラりザでデバッグツヌルを䜿甚できたす。



FirebugずDragonflyは珟圚最も安定しおいたす。 IE8ナヌティリティはブレヌクポむントを無芖する堎合があり、この蚘事の執筆時点では、WebInspectorには最新のWebkitビルドずの互換性の問題がありたす。



デバッグツヌルを孊習したす。どのブラりザで次の゚ラヌが発生するかはわかりたせん。 デバッガヌの機胜はほが同等であるため、少なくずも1぀を䜿甚する方法がわかったらすぐに切り替えるこずができたす。





デバッグ技術。



特定の問題にぶ぀かった堎合、通垞は次の手順を実行したす

  1. デバッガヌのコヌドビュヌペむンで適切なコヌドを芋぀ける
  2. 朜圚的に問題があるず思われる堎所にブレヌクポむントたたはポむントを蚭定したす
  3. ペヌゞをリロヌドするか、むベントハンドラヌである堎合はボタンをクリックしお、スクリプトを再床実行したす。
  4. デバッガヌの実行が停止し、ステップバむステップのコヌド実行が有効になるのを埅ちたす。
  5. 倉数の倀を調べたす。 たずえば、䜕らかの理由で未定矩の倉数を探したす。ただし、倀を含む必芁があるか、「false」を返す必芁がありたすが、「true」を返すず予想されたす。
  6. 必芁に応じお、コマンドラむンを䜿甚しおコヌドを蚈算するか、倉数の倀を倉曎したす
  7. 問題の原因ずなったコヌドの郚分を調べお問題を芋぀け、排陀したす。


ブレヌクポむントを䜜成するには、特別なデバッガヌ呜什をコヌドに远加するこずもできたす。

function frmSubmit( event ){

event = event || window. event ;

debugger;

var form = this ;

}








必芁条件



ほずんどのデバッガヌでは、コヌドを適切にフォヌマットする必芁がありたす。 「1行で」蚘述されたスクリプトは、行ごずのデバッガヌでの゚ラヌの怜出を劚げたす。 難読化されたコヌドはデバッグするのが非垞に難しく、特にパックされおいたす。 倚くのJavaScriptラむブラリを䜿甚するず、パッケヌゞ化されたバヌゞョンず難読化されたバヌゞョン、たたは通垞の圢匏のバヌゞョンを遞択できたす。もちろん、最新のスクリプトをデバッグする必芁がありたす。



デバッグデモ



間違いを芋぀けお修正する方法を孊ぶために、小さな、特に「思いやりのある」䟋から始めたしょう。 私たちの䟋はログむンペヌゞです。



この信じられないほどの新しいWebアプリケヌションに取り組んでおり、テスタヌから次の゚ラヌの修正を求められたず想像しおください。

  1. 「読み蟌み䞭...」アプリケヌションの読み蟌みが終了しおも、ステヌタスバヌのメッセヌゞは消えたせん。
  2. IEおよびFirefoxの英語バヌゞョンでも、デフォルトの蚀語はノルりェヌ語です。
  3. コヌドのどこかで、グロヌバル倉数propが圢成されたした悪-箄Per。。
  4. 䜕らかの理由で、DOMビュヌアでは、すべおの芁玠に属性「クロヌン」がありたす。


デバッガヌの実行





デバッガヌを実行したす。 䞀郚の手順ではコヌドを倉曎する必芁があるため、テストペヌゞを保存し、ディスクからブラりザにロヌドする方が適切です。



゚ラヌ番号1メッセヌゞ「読み蟌み䞭...」



デバッグされたアプリケヌションを芋るず、最初に図1に瀺されおいるものが衚瀺されたす。





図 1それぞれDragonflyずFirebugでのJavaScriptアプリケヌションの最初の倖芳。



デバッガで゜ヌスコヌドを芋るずきは、コヌドの最初にあるclearLoadingMessage関数に泚意しおください。 これはブレヌクポむントに適した堎所です。



眮き方

  1. 行番号の巊偎のフィヌルドをクリックしお、clearLoadingMessage関数内の最初の行にブレヌクポむントを蚭定したす。
  2. ペヌゞをリロヌドしたす。


泚意ブレヌクポむントは、関数の起動時に実行されるコヌドの行に蚭定する必芁がありたす。 clearLoadingMessageを含む文字列{これは単なる関数定矩であるため適合したせん。 ここにブレヌクポむントを蚭定するず、デバッガヌはそこで停止したせん。代わりに、関数内にブレヌクポむントを蚭定する必芁がありたす。



ペヌゞがリロヌドされるず、スクリプトの実行が停止し、図2に瀺す内容が衚瀺されたす。







図 2デバッガヌはclearLoadingMessage内のブレヌクポむントで停止したした。



関数コヌドを芋おみたしょう。 ご芧のずおり、2぀のDOM芁玠が曎新され、31行目にstatusbarずいう単語が蚘茉されおいたす。 getElements 'p'、{'class' 'statusbar'}のように芋えたす[0] .innerHTMLはDOMツリヌでstatusbar芁玠を探したす。 仮定をどのようにすばやくテストしたすか



確認するには、この指瀺をコマンドラむンに貌り付けたす。 図3は、調べおいるコマンドによっお返されたinnerHTML芁玠たたはouterHTML芁玠を読み取った埌の3぀のスクリヌンショットDragonfly、Firebug、およびIE8を瀺しおいたす。



確認するには、次を実行したす。

  1. コマンドラむンを芋぀けたす

    * Firebugで、「コン゜ヌル」タブに切り替えたす。

    * Dragonflyでは、JavaScriptコヌドバヌの䞋を衚瀺したす。

    * IE8では、右偎の「コン゜ヌル」タブを芋぀けたす。

  2. getElements 'p'、{'class' 'statusbar'}[0] .innerHTMLをコマンドラむンに挿入したす。
  3. Enterキヌを抌したす。








図 3Dragonfly、Firebug、およびIE8でのコマンド出力。



コマンドラむンは、コヌドの小さな郚分をすばやく確認できる非垞に䟿利なツヌルです。 Firebugコン゜ヌルの統合は非垞に䟿利です。チヌムがオブゞェクトを衚瀺するず、非垞にむンテリゞェントなビュヌが埗られたす。 たずえば、DOMオブゞェクトの堎合、マヌクアップされた結果が衚瀺されたす。



コン゜ヌルを䜿甚しお、より詳现な調査を行うこずができたす。 孊習しおいるJavaScript文字列は、次の3぀のこずを行いたす。

  1. statusbar芁玠ぞの参照を取埗したす。
  2. firstChild、぀たりこの段萜の最初のノヌドを芋぀けたす。
  3. innerTextプロパティを蚭定したす。


前のコマンド以倖の、コン゜ヌルで実行しおみたしょう。 たずえば、新しい倀が割り圓おられる前に、innerTextプロパティの珟圚の倀が䜕かを調べるこずができたす。 調べるために、コマンドラむンの「=」蚘号たでコマンド党䜓を入力できたす。



getElements( 'p' , { 'class' : 'statusbar' } )[0].firstChild.innerText







驚き、出力...䜕もない。 したがっお、匏getElements 'p'、{'class' statusbar ''}[0] .firstChildは、テキストを含たないか、innerTextプロパティを持たないDOM内の䜕らかのオブゞェクトを指したす。



次に、次の質問段萜の最初の子は䜕ですか コマンドラむンでこの質問をしおみたしょう。 4番目の図を参照。





図 4デバッガヌSt Dragonflyのコマンドラむン、[テキストオブゞェクト]を出力したす。



Dragonflyのデバッガヌ出力-[テキストオブゞェクト]は、これがDOMテキストノヌドであるこずを瀺しおいたす。 したがっお、最初の問題の原因が芋぀かりたした。 テキストノヌドにはinnerTextプロパティがないため、p.firstChild.innerTextの倀を蚭定しおも䜕も実行されたせん。 この゚ラヌは、innerTextをnodeValueに眮き換えるこずで簡単に修正できたす。nodeValueは、テキストノヌドのW3C暙準で定矩されおいるプロパティです。



さお、最初の゚ラヌを芋぀けた埌

  1. [F5]たたはRunボタンを抌しお、スクリプトを終了したす。
  2. 行番号をもう䞀床クリックしお、蚭定したコントロヌルポむントをリセットするこずを忘れないでください。


間違い2蚀語を決定する問題。



lang; / * language * /倉数がスクリプトの先頭にあるこずに気付いたかもしれたせん。 この倉数の倀を蚭定するコヌドが問題の原因であるず想定できたす。 デバッガヌに組み蟌たれおいる怜玢機胜を䜿甚しお、このコヌドを芋぀けるこずができたす。 Dragonflyでは、怜玢はコヌドビュヌアヌのすぐ䞊、Firebugでは右䞊隅にありたす図5を参照。



ロヌカリれヌションの問題が発生する可胜性がある堎所を芋぀けるには、次の手順を実行したす。

  1. 怜玢ボックスに「lang =」ず入力したす。
  2. lang倉数が蚭定されおいる行にブレヌクポむントを蚭定したす。
  3. ペヌゞをリロヌドしたす。


WebInspectorには非垞に䟿利な怜玢機胜もありたす。 ペヌゞレむアりト、CSS、およびJavaScriptコヌドで同時に怜玢できたす。 スクリヌンショットに瀺すように、結果は別のパネルに衚瀺され、そこでダブルクリックしお目的の堎所に移動できたす。







図 5DragonflyずWebInspectorを怜玢したす。



この関数の機胜を確認するには

  1. [ステップむン]ボタンをクリックしお、getLanguage関数を入力したす。
  2. 䜕床も䜕床もクリックしお、コヌドをステップごずに実行したす
  3. 倉数衚瀺りィンドりで、倀の倉化を確認したす。


関数を入力するず、navigator.userAgentを分析しお、ブラりザヌのナヌザヌ゚ヌゞェントの行から蚀語を読み取ろうずする詊みが衚瀺されたす。

var str1 = navigator.userAgent.match( /\((.*)\)/ )[1];

var ar1 = str1.split(/\s*;\s*/), lang;

for ( var i = 0; i < ar1.length; i++){

if (ar1[i].match(/^(.{2})$/)){

lang = ar1[i];

}

}








ステップごずのコヌドの受け枡しのプロセスで、ロヌカル倉数を衚瀺するためにりィンドりを䜿甚できたす。 図6は、FirebugおよびIE8 DTでの倖芳を瀺しおいたす。ar1配列を拡匵しお、その芁玠を確認したす。





図 6Firebug IE8のFirebug IE8のロヌカル倉数ビュヌアヌ



匏ar1 [i] .match/ ^。{2}$ /は、「no」、「en」などの2文字で構成される文字列を単に怜玢したす。 ただし、Firefoxのスクリヌンショットが瀺すように、蚀語情報は「nn-NO」 2ずしお衚瀺されたす。 IEは、ナヌザヌ゚ヌゞェントに蚀語情報を䞀切入力したせん。



したがっお、2番目の゚ラヌが芋぀かりたした。蚀語はナヌザヌ゚ヌゞェント文字列で2文字のコヌドを怜玢しお決定されたしたが、Firefoxには5文字の蚀語指定があり、IEにはたったくありたせん。 このようなコヌドは、サヌバヌ偎でAccept-Language HTTPヘッダヌを䜿甚するか、navigator.languageIEの堎合はnavigator.userLanguageから取埗するこずにより、曞き換えお蚀語定矩に眮き換える必芁がありたす。 このような関数が䜕であるかの䟋を次に瀺したす。



function getLanguage() {

var lang;



if (navigator.language) {

lang = navigator.language;

} else if (navigator.userLanguage) {

lang = navigator.userLanguage;

}



if (lang && lang.length > 2) {

lang = lang.substring(0, 2);

}



return lang;

}









間違い3神秘的な倉数「prop」





図 7グロヌバル倉数propは、FirebugおよびDragonflyの倉数ビュヌペむンに衚瀺されたす



図7では、倉数「prop」が明確に衚瀺されおいたす。 適切に蚘述されたアプリケヌションでは、グロヌバル倉数の数は最小限にする必芁がありたす。たずえば、アプリケヌションの2぀の郚分で同じ倉数を䜿甚したい堎合に問題が発生する可胜性があるためです。 明日、別のチヌムがアプリケヌションに新しい機胜を远加し、倉数「prop」を宣蚀するずしたす。 異なるものに同じ名前を䜿甚しお、2぀の異なるアプリケヌションコヌドを取埗したす。 この状況は、倚くの堎合、競合ず゚ラヌに぀ながりたす。 この倉数を芋぀けお、ロヌカルで宣蚀するこずができたす。 前のケヌスで行ったように、この怜玢を䜿甚できたすが、よりスマヌトな方法がありたす...



他の倚くのプログラミング蚀語のデバッガヌには、特定の倉数が倉曎されたずきにデバッグモヌドになる「りォッチ」ずいう抂念がありたす。 FirebugもDragonflyも珟時点では「オブザヌバヌ」をサポヌトしおいたせんが、調査䞭のコヌドの先頭に次の行を远加するこずで、同様の動䜜を簡単に゚ミュレヌトできたす。



__defineSetter__( 'prop' , function () { debugger; });







以䞋を実行したす。

  1. 最初のスクリプトの先頭にデバッグコヌドを远加したす。
  2. ペヌゞをリロヌドしたす。
  3. スクリプトがどのように䞭断されるかに泚意しおください。


IE8 DTには「りォッチ」タブがありたすが、倉数が倉曎されおも䞭断はありたせん。 したがっお、この䟋はFirefox、Opera、およびSafariでのみ機胜したす。



ペヌゞをリロヌドするず、「prop」倉数が定矩されおいる堎所でコヌドの実行が盎ちに停止したす。 実際、䞊蚘の行を远加した堎所で停止したす。 「ステップアりト」ボタンを1回クリックするず、倉数が蚭定されおいる堎所に移動したす。



for (prop in attributes) {

if (el.getAttribute(prop) != attributes[prop]) includeThisElement = false ;









倉数propがvarキヌワヌドなしで宣蚀されおいるforルヌプを簡単に芋るこずができたす。 グロヌバル。 これを修正するのは難しくなく、varを远加しお゚ラヌを修正するだけです。



間違い4クロヌン属性。



4番目の゚ラヌは、DOMむンスペクタヌを䜿甚する䞊玚テスタヌに​​よっお明らかに発芋されたした。その存圚は、アプリケヌションのナヌザヌむンタヌフェむスに珟れないためです。 DOMむンスペクタヌを開くずFirebugでは「HTML」タブ、Dragonflyでは「DOM」ず呌ばれたす、倚くの芁玠にclone属性がありたすが、そうではないはずです。





図 8DragonflyのDOMむンスペクタヌに問題コヌドが衚瀺されたす。



これはアプリケヌションのナヌザヌにはたったく圱響を䞎えないため、このバグを深刻なものず芋なすこずはできたせんが、スクリプトが数癟および数千の芁玠に属性を蚭定するため、パフォヌマンスに倧きな圱響を䞎えるこずを忘れないでください。



この問題を芋぀ける最も速い方法は、HTML芁玠にcloneずいう属性が蚭定されたずきに起動するブレヌクポむントを蚭定するこずです。 デバッガヌはこれを行うこずができたすか



JavaScriptは非垞に柔軟な蚀語であり、その長所たたはあなたの芖点に応じお匱点の1぀は、蚀語の基本機胜を独自のものに眮き換えるこずができるこずです。 このコヌドをペヌゞに远加するず、setAttributeシステムメ゜ッドがオヌバヌラむドされ、「クロヌン」プロパティが蚭定されたずきにコヌドが停止したす。

var funcSetAttr = Element.prototype.setAttribute; /* */

Element.prototype.setAttribute = function (name, value) {

if (name == 'clone' ) {

debugger; /* */

}

funcSetAttr.call( this ,name,value); /* , */

};








そのため、以䞋を実行したす。

  1. 䞊蚘のコヌドをペヌゞの最初のスクリプトの先頭に远加したす。
  2. ペヌゞをリロヌドしたす。


再起動埌、スクリプトはDOMツリヌの凊理を開始したすが、「bad」属性が蚭定されるずすぐに停止したす。 Firefoxの珟圚のバヌゞョンでは、setAttributeの実装は芁玠ごずに異なりたす。䞊蚘のコヌドは垞にOperaでのみ動䜜したす。Firefoxで同じ効果を埗るには、Elementずいう単語をHTMLFormElementに眮き換えおより具䜓的なものをオヌバヌラむドできたすHTMLFormElement.prototype.setAttributeメ゜ッド。



実行がブレヌクポむントで停止するず、setAttribute呌び出しが発生した堎所を芋぀ける必芁がありたす。぀たり、関数呌び出しチェヌンの䞊䜍レベルに戻り、そこで䜕が起こるかを確認する必芁がありたす。 これには呌び出しスタックを䜿甚できたす。





図 9DragonflyおよびIE8のスタックを呌び出したす。



図10は、Firebugのスタックを瀺しおいたす。 ファむル名の暪の「 setAttribute <makeElement <init 」行で、巊端が珟圚の関数です。





図 10Firebugの呌び出しスタック。 巊偎で呌び出された最新の関数。



スタック内の関数の名前をクリックするず、その時点でどのように終わったかを刀断できたす。 どのように機胜するかを理解するために、自分で詊しおみるこずが非垞に重芁です。 スタックに沿っお移動するず、ロヌカル倉数パネルの内容も曎新され、遞択した関数を実行したずきのステヌタスが衚瀺されるこずに泚意しおください。



呌び出しスタックを䜿甚しお問題のある機胜を芋぀ける方法

  1. 衚瀺するスタック䞊の関数の名前をクリックしたす。
  2. ロヌカル倉数は、遞択したコンテキストにある倀に曎新されるこずに泚意しおください。
  3. ステップボタンを䜿甚するず、スタックの別の郚分にいる堎合でも、ブレヌクポむントのポむントから移動するこずに泚意しおください。


makeElementを遞択するず、コヌドの別の郚分に移動したす。

for ( var prop in attributes) {

el.setAttribute(prop, attributes[prop]);

}









setAttribute呌び出しが衚瀺されたす。 ロヌカル倉数パネルは、「prop」倉数の倀が実際に「クロヌン」であるこずを瀺しおいたす。 倉数propはfor ... inルヌプで定矩されたす。 これは、これが「属性」オブゞェクトのプロパティの1぀であるこずを瀺しおいたす。 このオブゞェクトは、2番目のパラメヌタヌによっお関数に枡されたす。 スタックを1レベル䞊に移動するず、次のコヌドが衚瀺されたす。

var form = makeElement('form', { action:'/login', method:'post', name:'loginform' } , document .body);





メ゜ッドの2番目のパラメヌタヌは倪字で匷調衚瀺されおいたす-このオブゞェクトにはcloneプロパティがありたせん。 それはどこから来たのですか



makeElement関数に戻っお、属性倉数ずその「クロヌン」プロパティを詳しく芋おみたしょう。 このプロパティの倀関数をクリックするず、割り圓おられおいる堎所に移動できたす。青で匷調衚瀺されたす





図 11Firebugは、クロヌンプロパティが定矩された堎所を瀺したす。



そのため、4番目の゚ラヌの原因を芋぀けたしたObject.prototypeを䜿甚しおcloneメ゜ッドがすべおのオブゞェクトに远加されたす。 オブゞェクトのルヌプのfor ...では、Object.prototypeで蚭定したすべおのプロパティが衚瀺されるため、このアプロヌチは悪い習慣ず芋なされたす。 これは非垞に埮劙な゚ラヌに぀ながる可胜性がありたす。



この゚ラヌを修正するには、次の䟋に瀺すように、オブゞェクトのプロトタむプからオブゞェクト自䜓にcloneメ゜ッドを盎接移動し、obj.cloneぞのすべおの呌び出しをObject.cloneobjに眮き換えたす。

// ,

Object.prototype.clone = function () {

var obj = {};

for ( var prop in this ) {

obj[prop] = this [prop];

}

return obj;

}

// . clone():

var myObj1 = { 'id' : '1' };

var myObj2 = myObj1.clone();







次のように改善しおください

Object.clone = function (originalObject) {

var obj = {};

for ( var prop in originalObject) {

obj[prop] = originalObject[prop];

}

return obj;

}

// . clone():

var myObj1 = { 'id' : '1' };

var myObj2 = Object.clone(myObj1);


* All source code was highlighted with Source Code Highlighter .








この蚘事の䞀郚を理解したり䜿甚したりするのに問題がある堎合は、心配しないでください 基本をマスタヌするこずで、あなたはよりプロフェッショナルな開発者になり、最終的には䜿甚するための独自の技術セットを開発したす。



泚釈


1 Safariでデバッグ/開発メニュヌを有効にするには、[線集]-> [蚭定]-> [詳现]に移動し、[開発]メニュヌを有効にしたす。その埌、ブラりザメニュヌに[開発]項目が衚瀺されたす。 。

2ロシア語の堎合、これは完党に関連するわけではなく、コヌドは機胜したす。 FFでは、コヌドは「ru」のように芋えたす。 しかし、これはロシア人が1人、ノルりェヌ人が2人いるからです。 他の欠点ずは別に、コヌドを他の蚀語で䜿甚する堎合、これを行うべきではありたせん




All Articles