{"id":92051,"date":"2015-11-19T07:00:00","date_gmt":"2015-11-19T22:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/20151119-00\/?p=92051\/"},"modified":"2019-03-13T12:21:59","modified_gmt":"2019-03-13T19:21:59","slug":"20151119-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20151119-00\/?p=92051","title":{"rendered":"Stupid JavaScript debugging tricks: Abusing the conditional breakpoint"},"content":{"rendered":"<p>Your favorite JavaScript debugger may very well have a conditional breakpoint facility, and if it does, you can abuse it to do things unrelated to conditional breakpoints. <\/p>\n<p>Since conditional breakpoints are based on evaluating an expression, you can use an expression with side effects, like, say, logging. <\/p>\n<table BORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\" STYLE=\"border: solid 3px #ebebeb;font-family: Segoe UI, sans-serif;width: 30em;color: black;background-color: #f0f0f0\">\n<tr>\n<td ALIGN=\"center\" STYLE=\"background-color: white;padding: 5px\">Breakpoint Condition<\/td>\n<\/tr>\n<tr>\n<td STYLE=\"border: solid 1px #dadada;padding: 10px\">\n<p>When the breakpoint location is reached,     the expression is evaluated and the breakpoint     is hit only if the expression is true or has changed.     <\/p>\n<table BORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"2\">\n<tr>\n<td>&#x2612;<\/td>\n<td>Condition:<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td STYLE=\"border: solid 1px gray;background-color: white;width: 30em\">    console.log(&#8220;click received&#8221;)<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>&#x2d59; Is true<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>&#x2d54; Has changed<\/td>\n<\/tr>\n<\/table>\n<p ALIGN=\"right\">\n<table BORDER=\"0\" CELLSPACING=\"5\" CELLPADDING=\"2\" STYLE=\"text-align: center\">\n<tr>\n<td STYLE=\"border: solid 2px black;width: 9em\">OK<\/td>\n<td STYLE=\"border: solid 1px black;width: 9em\">Cancel<\/td>\n<\/tr>\n<\/table>\n<\/td>\n<\/tr>\n<\/table>\n<p>The <code>console.log<\/code> function returns <code>undefined<\/code>, so the condition is never true, but that&#8217;s okay, because we&#8217;re executing the expression for its side effect of printing a string to the console. <\/p>\n<p>Here, we just logged a hard-coded string, but you can log any expression you want. For example, you could use <\/p>\n<pre>\nconsole.log(\"current selection is \" + this.currentSelection)\n<\/pre>\n<p>Or even more fun: <\/p>\n<pre>\nconsole.log(getStack())\n<\/pre>\n<p>where you&#8217;ve defined <\/p>\n<pre>\nfunction getStack() { try { throw new Error(); } catch (e) { return e.stack; } }\n<\/pre>\n<p>What, you didn&#8217;t define that function? No problem. Just evaluate it in your immediate window and boom, now it&#8217;s defined. <\/p>\n<p>Now, printing an entire stack trace may be excessive. So store it in your object for future inspection. For example, you might do this in a constructor so that you have a stack trace of how your object got created. That way, when you have a transaction that failed to complete, you can look at the cached stack trace to see how the transaction got started. <\/p>\n<pre>\n(this._stack = getStack()) === 42\n<\/pre>\n<p>The extra <code>=== 42<\/code> at the end is to ensure that the value of the expression is falsy. <\/p>\n<p>Anyway, just a few quick tips for JavaScript debugging. I didn&#8217;t come up with these ideas, but I&#8217;m sharing them. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Code injection.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-92051","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Code injection.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/92051","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=92051"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/92051\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=92051"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=92051"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=92051"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}