Is it possible to make a variable easily accessible by the debug console without actually making it global? For example, something like this in the code:
console.$ = jQuery
And then in the console, I'd like this to work:
$('#foo')
Not while the page isn't paused at a breakpoint, no. But when the page is paused at a breakpoint, the console has access to all variables that are in-scope at the point where it's stopped.
Of course, your console.$ = jQuery example does make it possible to do
console.$("#foo")
...in the console.
Side note: console.$ = jQuery and $("#foo") aren't great examples, as jQuery is almost always global, and even if you don't have jQuery loaded on your page at all, Chrome provides its own $ function in the console, and I think at least one other browser does as well...
Related
Very often I hack and play with the JavaScript code on some website. Many times JavaScript code is secured in a function:
(function(){
var = ...
...
}());
and I cannot access the object defined in that scope.
Moreover such code is only executed once, when the page loads, thus modifying it with the chromium/google-chrome developer console (Sources toool) is useless.
Is there any simple way to live-edit some JavaScript code in a page and reload the page so that it runs the modified code?
Have a look at using something like Tampermonkey https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo?hl=en
the Chrome equivalent of Firefox's Greasemonkey
EDIT: you could use this in combination with adblock to disable the loading of the script you are targeting: https://stackoverflow.com/questions/13919183/how-to-turn-off-one-javascript-or-disable-it-under-chrome
I wouldn't call it simple, but something like Intercept Proxy might be able to do it -- replacing one file with another.
I found a way to achieve what I needed.
Using Chromium's debugger I can set a breakpoint on any statement of the source code.
Once that statement is executed, the code suspends and Chromium's console gives me access to whatever is in the stack of the current function.
Chrome on iOS appears to create an XMLHttpRequest object when you include an external JavaScript file. It seems to assign this object to a global variable with the identifier a, overwriting anything you may have already had in there.
Test case:
HTML file (test.html):
<!-- ... -->
<script>
var a = 1; // Value is not important for this demonstration
</script>
<script src="test.js"></script>
<!-- ... -->
External JavaScript file (test.js):
setTimeout(function () {
document.write(a); // [object XMLHttpRequest]
a.onreadystatechange = function () {
document.write(a.readyState); // Alternates between "1" and "4"
};
}, 100);
The XMLHttpRequest appears to repeatedly make a request (to somewhere... routing the device connection through a proxy and monitoring requests doesn't show up anything) and the onreadystatechange event handler is repeatedly executed.
Some more observations:
This only seems to happen some time after page load (hence the setTimeout)
When it does happen, there is also a window.__gchrome_CachedRequest property
__gchrome_CachedRequest === a
It doesn't seem to happen in older versions of iOS Chrome (not sure which version it first occurs in though)
Has anyone come across this before? Is there a way I can stop it from happening (Note... I cannot rename a)? If anyone knows why it does this I would love to find out.
Update
I've just noticed that this actually happens with inline scripts too, not just when you include an external script. I didn't notice this initially because I didn't have the setTimeout call in there. So it looks like it actually just always happens some time after page load.
From the discussion we had in comments, it looks like Chrome is using a with statement to layer some of its own stuff over the top of window properties. It probably does this because those properties would not normally be overwritable. The delay is most likely down to how soon Chrome can inject its own script into the UIWebView (browsers on iOS are forced to use the underlying UIWebView object rather than their own engines) after a page starts loading.
If all this speculation is actually true, then there's simple solution, other than to access window.a instead of a or take the power back and use your own with statement:
with (window)
eval(myScript);
Hardly a solution anyone would relish implementing, but might be your only option.
I have seen jquery-ui-1.8.11.js verify console.log functionality by doing
if (this.debug)
console.log()
I have also seen people define an anonymous function that is a no-op for browsers with no console logging like IE7.
if(typeof console === "undefined") {
console = { log: function() { } };
}
Is there a technical difference or are both functionally equivalent?
In the first example you've given, this.debug will be a reference to a debug variable in the jQueryUI code. This debug variable will have been set elsewhere, possibly by checking whether console is defined, but also possibly with other settings.
In any case, the first example is specific to the application; if you want to do a generic check to see whether the console is available, you'll need to use the second technique. You don't have to define an empty console object as per the example, but doing it that way does mean that you won't have to do the if() condition every time you want to call console.log().
Having said all of that, I would counsel you strongly to avoid putting any code into production which contains calls to the console. The console should only be used for debugging purposes while you are working on the code. It should not be necessary in final release, and doing so can be a sign that either your code is unstable or you're unconfident of it, neither of which is a good sign if you're releasing the code for live use.
(libraries such as jQueryUI are an exception to this rule, as they need to provide functionality for developers to do debugging while writing code using their library)
Both of those do something else. The first code suppresses logging messages unless a flag is set. The people who develop jQuery UI need logging when working on it, and turn it on. But people using the library don't want to have their console cluttered by log messages from libraries, so it's off by default. It lets you turn off logging even when the browser supports it – that regular users on IE7 don't get script errors is a (possibly intended) side effect.
The second code defines a dummy console.log(), so you can call the method without checking if it exists everywhere. It will not suppress logging on browsers where it's supported.
The second of the two is standalone, not relying on jQuery. In my opinion, that makes it better.
With firefox w/firebug, can I type javascript into the browser and test things?
Can I also reference functions/objects from .js files references in the html?
Short answer: Yes, you can, by using the console.
Longer answer: Take a look at the What's new in Firebug 1.6 video, it gives an excellent demonstration on what you can do with the console, including auto-completion of the available variables.
Everything that's available globally in the current document is available to the console. So if you included jQuery on the current page, it'll be accessible from the console too.
Yes, if you enable the console tab you can use it as a Javascript REPL. From there you should be able to access any variables and objects in the global scope.
yes, you can... while on firebug (1.6.1) click 5th button from the left, its like a bunch of lines, entitled show command line then you will see it.
as for your second question... u can use it as long as it is on the DOM otherwise goodluck to u :)
I just started doing some Javascript work for a project, I do mostly backend work so I'm sorry for being new at this! Also, not using a Javascript framework because I want to learn about the fundamentals before making everything very easy for myself :)
So, here is my question/confusion: I wrote a little javascript that dynamically changed forms. This is how I called the code:
// loads the initial box
window.onload = initList(environment_box);
// loads artifacts on each change to environment select box
environment_box.onchange = changeList;
This worked like magic - in CHROME that is! I never noticed it wasn't working in Firefox (its just an internal tool, so I can assume decent browsers, but I figure hey, if its working in Chrome, it will work in Firefox!). So, I did some investigation, and it seems as though the code isnt getting executed in Firefox. I whipped out firebug and wanted to see what was going on.
The interesting thing was, when I enabled Console on firebug, my code got executed! I am very confused as to why, and I would much appreciate any help I could get. Thanks!
-Shawn
You are calling some method on console in your JavaScript is my best guess. Chrome has console defined be default, so it is not a problem.
On Firefox, however, there is no such global object (not without Firebug), so when you try to call a property on an undefined object like,
console.log(..);
it throws an exception which you are not catching, so the JavaScript execution halts.
You're probably calling a method of the console object which just doesn't exist by default in most web browsers. It may be always available on webkit based browsers (like Chrome) but with firefox/IE(/opera?) it requires an external add-on, either firebug or a javascript dependency.
Checkout things like firebugx which simply defines the most common methods of a console object as no-op functions.