My JS code is getting bigger and bigger and also older. This means that, while working on other projects, I tend to forget all the sequences in which I call my functions. I would like to know if there's a tool which can parse my .js file and produce a (simple) document in which each function has listed all the other function it call. This is just a static source code analysis; I don't need it to do anything at run time.
Overly simplified example:
function firstFunction(){
...
secondFunction();
thirdFunction();
}
function secondFunction(){
...
thirdFunction();
}
function thirdFunction(){
...
secondFunction();
firstFunction();
}
The resulted (text) document would simply list the function calls (I don't care about format):
firstFunction: secondFunction, thirdFunction
secondFunction: thirdFunction
thirdFunction: secondFunction, firstFunction
EDIT: please note that I would like not to change my code; I have tens of functions with some of them calling more than 10-15 other functions; printing messages before or after each function call would require to much time, both for writing and running each scenario.
EDIT no.2: I could do this with any basic text editor by selecting each function name and searching for instances of that name in the file; this method would require much more time and brain cells than I can afford right now; an automated tool would have been perfect.
console.trace() works very well on Google Chrome. In addition console.log() could be handy, when console.log() is called, the stacktrace is also displayed.
Related
I'm trying to debug something live on a customer website and my code is all inside an anonymous function block. I don't know if there's anyway to reach that code to execute functions or look at variables in there. I can't put a breakpoint either because this code is dynamically generated each time the page is refreshed and the breakpoint doesn't stick.
(function() {
var Date = "14 September 2022 14:44:55"; // different every refresh for example
var Holder = {
var Items = {
item1: "Value1",
item2: "Value2"
};
function getItem(name) {
return Items[name];
};
function setItem(name, value) {
Items[name] = value;
};
setTimeout(DoSomething(), 2000);
})();
That's not the actual code, just a bare minimum example to illustrate the problem.
Is there anyway to get reach getItem() or Items?
Without a breakpoint that code probably runs to completion then POOF it's all gone anyway.
Redefine setTimeout
If it really is the case that the code inside the anonymous function calls other browser methods, you might be able to insert a detour at runtime that you can then put a breakpoint on.
For this to work, you will need to be able to inject new code into the page before the anonymous code, because there's no other way to invoke the IIFE.
Your example code uses setTimeout, so here's what I would try to insert:
let realSetTimeout = window.setTimeout
window.setTimeout = (...args) => {
debugger
return realSetTimeout(...args)
}
Lots of unrelated code might be calling setTimeout, in which case this could break the page or just make debugging really tedious. In that case, you might make it only debug if one of the setTimeout args has a value that's used in your example, e.g.:
// only break for our timeout
if(args[1] === 2000) debugger
Something like that might not trigger for only your code, but it would hugely reduce the number of other codepaths that get interrupted on their journey through the commonly-used browser capability.
Alternatively, use Charles Proxy to rewrite the body of the HTML page before it enters your browser. You could manually insert a debugger call directly into the anonymous function. Charles is not free, but I think they have a demo that might let you do this. If you do this professionally, it's probably a good purchase anyway. Your employer might even pay for the license.
If you can't use Charles (or a similar tool), you could instead set up a local proxy server using Node which does the rewrite for you. Something like that might only take an hour to throw together. But that is a bigger task, and deserves its own question if you need help with that.
No unfortunately.
The variables inside of the anonymous object are created in a scope which is inaccessible from the outside.
One of the main benefits of using a closure!
You’ll have to find a way to insert your own code inside of it by modifying the function that is generating those objects. If you can’t do that, then you’ll have to take the fork in the road and find another way.
I'm having major trouble getting my app to behave while loading. I don't think it is very fair to users to allow them access to the app until it's finished loading and is ready / responsive.
Please note: every thing else works fine in my app I just can't get functions to run in order.
function LOADINGapp(){
//app loads but allows user to enter before loading is finished
$.when(getToday()).then(reorderdivs()).then(getSomething()).then(setupSomethingElse()).then(loadAnotherSomething()).then(INITapp());
//app stops dead at getToday but (Crome javascript console) no errors
getToday(function(){reorderdivs(function(){getSomething(function(){setupSomethingElse(function(){loadAnotherSomething(function(){INITapp();});});});});});
//app loads but allows user to enter before loading is finished
getToday(reorderdivs(),getSomething(),setupSomethingElse(),loadAnotherSomething(),INITapp());
//getToday();
//reorderdivs();
//getSomething();
//setupSomethingElse();
//loadAnotherSomething();
//INITapp();
}
function INITapp(){
$('#SPLASH').hide();
}
Can someone please assist me, I don't understand. Done and doing a tone of research to get this to behave.
Thanks
I haven't used when/then from jquery before, but it looks like you need to pass the pointers to the methods. Right now you are actually executing them all at once. Try:
$.when(getToday())
.then(reorderdivs)
.then(getSomething)
.then(setupSomethingElse)
.then(loadAnotherSomething)
.then(INITapp);
(Notice the missing parentheses)
Also, be aware the only true asynchronous object in JS is an AJAX call. setTimeout is NOT asynchronous, it is a queueing method. Read John Resig's post:
http://ejohn.org/blog/how-javascript-timers-work/
I solved it by jumping (only allowing my LOADINGapp function to do one thing at a time) so it works in stages. once a stage (a function) is complete it jumps back into the LOADINGapp function.
var L=0;
function LOADINGapp(){
if(L==0){getToday();}
else if(L==1){reorderdivs();}
else if(L==2){getSomething();}
else if(L==3){setupSomethingElse();}
else if(L==4){loadAnotherSomething();}
else if(L==5){INITapp();};
}
function INITapp(){
$('#SPLASH').hide();
}
example:
function getSomething(){
//app suff
//app suff
//app suff
L = 3;
LOADINGapp();
}
the only thing I will improve is just do L++; at the end of LOADINGapp as it saves writing it all over the place. PS:thanks for the efforts guys
It is probably something to do with asynchronous functions. So you could try making those functions with a callback, as mentioned here: http://pietschsoft.com/post/2008/02/JavaScript-Function-Tips-and-Tricks.aspx.
I would like to be able to perform manipulations on a given JS app, and then simply get a large log of all the functions that have been called. This is possible in Chrome, but only if one puts a breakpoint somewhere. My problem is when I am reverse-engineering a given website (only for self-teaching purposes, of course) it often takes me a whole lot of time to figure out where to even start from. Something like that will help me tremendously because I will no longer have to search within the code, rather, I will just do a user action, and grab the stack log afterwards.
I suppose that there should be a way to intercept (or wrap) every function call, so that it is dumped to the log before the function is called.
Try this article:
http://eriwen.com/javascript/stacktrace-update/
or this post:
http://ivan-ghandhi.livejournal.com/942493.html
and, probably, this: How can I get a Javascript stack trace when I throw an exception?
In Firebug, you can use the profiler to log every function called. Use console.profile() and console.profileEnd() to trigger it programatically.
However, this will not give you proper stack traces. (Are you sure that's what you want?)
To log methods of specific objects, you can overwrite them like so:
for (var key in obj) {
if (typeof obj[key] == 'function') {
(function(){
var origFun = obj[key];
obj[key] = function () {
var result = origFun.apply(this, arguments);
console.log('call to method', key, 'with arguments', arguments,' - Result:', result);
// console.trace(); // for a trace with every call
return result;
};
})();
}
}
Maybe aspect oriented programming (AOP) can provide an answer. I just found out about aspectJS which could help intercept and log function calls
You can use dynatrace. Dynatrace is a profiling tool for IE and FF. Dynatrace can monitor your application while it is running, and then serves you a timeline of all what happened. In the timeline, there is blocks representing the javascript activity. You can right-click on it (purepath), and then walk through the whole call stack. You can export that to excel or other If you want.
You can add markers in your code, those markers will appear on the timeline and in the purepath:
if(typeof(_dt_addMark)!="undefined") _dt_addMark('MyCustomTimerName');
alternatively, if you only want to find "a way to intercept (or wrap) every function call",
there is a low-tech solution, if you are using a real webbapp (single-load javascript app):
bookmarklets
With bookmarklets, once you have loaded your page, you can execute some custom javascript. So what you can do there, is to override the functions methods that you want to observe with the same function containing logging (so just copy and paste the function, and add some console.log in there). This actually works even with native js functions.
I am trying to debug legacy scripts with Firebug. As per my knowledge (Which I got yesterday)
we use Step over (F10) to debug line by line and Step into (F11) to dig into JS function.
But when I use Step into on any JS function call, it takes control to next line. I want to see what is hidden inside the function. How can we do it ?
I kept break-point inside the function and then tried Step into then it takes control inside the function body. But it is tedious to find each function method and set break-point.
Is there any other way to do it ? or which is the right way ?
For example :
i2b2.ONT.ctrlr.FindBy = {
clickSearchName: function() {
// do some stuff
i2b2.ONT.ctrlr.FindBy.doNameSearch(search_info); // I tried Step into here
// some more stuff
}
doNameSearch: function(inSearchData) {
// If I set break-point here then only I can debug it
// or it directly takes control to `// some more stuff` in `clickSearchName:function`
}
}
PS: It also more external JS function calls.
Thanks,
Ajinkya.
"Step into" will step into the function if there is JS source for the function. If not (like for document.getElementById("foo"), it will step over it since it doesn't have anything that it understand to step into.
If you can point us to a working example where you are having the problem (either a jsFiddle reduction of the problem or a working web page) with instruction on where the relevant code is, we can probably help more.
Judging by your code example, I'm wondering what you're trying to step into. The line of code that starts with clickSearchName defines a function. It doesn't execute it. So, it won't go into that function until some later code actually calls clickSearchName. So, perhaps you're breaking on the definition of the function and trying to step into the function when it isn't being executed. That's just a guess though since we don't have a working example to try ourselves.
Add the line debugger; to your code at the place where you want to break into the debugger, it's a JavaScript keyword, which should do what you want. Just remember to take it out when you're done debugging your code.
Could someone explain the javascript that makes up Google's Website Optimiser Control script? Specifically: the first two lines, which seem to be empty functions, and why is the third function wrapped parentheses () ?
As far as I can tell this script is basically writing out a new <script> which presumably loads something for A/B testing.
function utmx_section(){}
function utmx(){}
(function() {
var k='0634742331',d=document,l=d.location,c=d.cookie;
function f(n) {
if(c) {
var i=c.indexOf(n+'=');
if (i>-1) {
var j=c.indexOf(';',i);
return escape(c.substring(i+n.length+1,j<0?c.length:j))
}
}
}
var x=f('__utmx'),xx=f('__utmxx'),h=l.hash;
d.write('<sc'+'ript src="'+'http'+(l.protocol=='https:'?'s://ssl':'://www')+'.google-analytics.com'+'/siteopt.js?v=1&utmxkey='+k+'&utmx='+(x?x:'')+'&utmxx='+(xx?xx:'')+'&utmxtime='+new Date().valueOf()+(h?'&utmxhash='+escape(h.substr(1)):'')+'" type="text/javascript" charset="utf-8"></sc'+'ript>')
}
)();
I've attempted to step through with the firebug debugger but it doesn't seem to like it. Any insights much appreciated.
Many thanks
inside anonymous function it shortens names of document and cookies inside it at first, function f(n) gets value of cookie under name n. Then Google reads its cookies and with help of d.write it loads its scripts (as I see they are related to Google Analytic). This way it makes On-Demand JavaScript loading... Actually you load these scripts all the time, Google just needs some additional parameters in url, so this is done this way - save parameters in cookie, which next time are used to get script again.
And finally back to the first two magic lines :) After Google loads its script (after executing d.write), there are some functions which uses utmx and utmx_section, as well as definition of these functions, or better to say overriding. I think they are empty at first just because another function can execute it before its real definition, and having empty functions nothing will happen (and no JS error), otherwise script would not work. E.g. after first iteration there is some data, which is used to make real definition of these functions and everything starts to work :)
The first 2 functions are in fact empty, and are probably overridden later on.
The third function is an anonymous self-executing function. The brackets are a convention to make you aware of the fact that it is self executing.
the "f" function looks up the value given to it in the document's cookies and returns it. Then a new script tag is written to document (and requested from server) with these values as part of its URL.