2

I'm trying to list the functions defined by the user in javascript.

So far I have:

for (i in window)
    if (typeof(window[i])==='function')
        alert(window[i]);

jsfiddle: http://jsfiddle.net/sCK9v/1/

it only lists functions but (in Firefox) that includes a lot of system ones, listed as having [native code].

Is there a way to get the functions actually defined by the page?

Barney
  • 16,181
  • 5
  • 62
  • 76
boisvert
  • 3,679
  • 2
  • 27
  • 53
  • Can't you filter out the [native code] ones? – Sebas Jul 24 '13 at 22:11
  • @Sebas, that's exactly what I'm stuck with :) – boisvert Jul 24 '13 at 22:12
  • @Sebas Good idea, but what if the user-defined function happens to happens to contain `[native code]`, say in a string? – Niet the Dark Absol Jul 24 '13 at 22:13
  • `if(o.toString().indexOf('[native code]') != -1) ...` – bfavaretto Jul 24 '13 at 22:14
  • 2
    What is the relationship between `i` and `o`? Don't you need a `var o = window[i];` somewhere? – Mike Samuel Jul 24 '13 at 22:14
  • 1
    @boisvert if you're stuck with [native code] you are pretty much on the edge of reasonable possibilities, the next step would be to write a lexer to analyze all – Vengarioth Jul 24 '13 at 22:15
  • you can check for ONLY "[native code]". example: function [\w$]*\(\) \{ \[native code\] \}/.test(atob); it's still possible to "fake" natives with custom toString()s, but this will prevent accidental detection in stuff like the code used to find natives using indexOf... – dandavis Jul 24 '13 at 22:28
  • exact duplicate of [List of global user defined functions in JavaScript?](http://stackoverflow.com/questions/493833/list-of-global-user-defined-functions-in-javascript) – Bergi Jul 24 '13 at 22:30
  • Exact duplicate, the answer here is better though! – Barney Jul 26 '13 at 08:47

3 Answers3

3

Before all other script execution:

var nativeFunctions = (function(o, i){
    for(i in window){
         if(typeof window[i] =='function'){
             o[i] === true;
        }
     }
     return o;
}({}));

And, when you want to check for new global functions:

var userFunctions = (function(o, i){
    for(i in window){
         if(!nativeFunctions[i] && typeof window[i] =='function'){
             o[i] === true;
        }
     }
     return o;
}({}));
Barney
  • 16,181
  • 5
  • 62
  • 76
  • @barney, can't see it... The first lists all functions - native or not - and the second lists those that aren't functions after all. Or what am I not getting? – boisvert Jul 25 '13 at 00:02
  • If you run the first before all other script execution, it will get the `window` object in its freshest instance (before anything can be appended to it). The second one filers `window` methods for a) not being present in step 1 (`!nativeFunctions[i]`) AND whether they're functions or nots (`typeof window[i] =='function'` — as before) – Barney Jul 25 '13 at 12:00
  • @barney, I finally worked it out. It has another advantage: it could filter some functions from others - e.g. JQuery or not... Based on when the test is done. – boisvert Jul 26 '13 at 14:22
  • @boisvert you know what — I actually think [basilikum's solution](http://stackoverflow.com/a/17846469/356541) is better. It's much terser, doesn't have the setup cost of storing a variable for comparison, doesn't rely on timing… And you could still filter with a new condition in the if statement. – Barney Jul 26 '13 at 15:33
  • 1
    @barney - that's what I thought at first. But when I tested it I found some functions weren't caught by it (and therefore are probably not inherited through the window's prototype - that was in Firefox). – boisvert Jul 26 '13 at 22:48
2

if you use Function.toString(); you get the body of a function, for native implemented functions / bindings in Gekko (Firefox) and V8 (Chrome) this returns a string like

"function functionName() { [native code] }"

you could filter by this.

if this doesnt suit you, you need to write a lexer (or lexical analyzer) to find out whats going on in all the script tags in the document

Vengarioth
  • 684
  • 5
  • 13
2

I think hasOwnProperty should already filter out all the native functions, because they are defined in the prototype of window and not in window itself:

for (i in window) {
    if (window.hasOwnProperty(i) && typeof(window[i]) === 'function') {
        alert(window[i]);
    }
}
basilikum
  • 10,378
  • 5
  • 45
  • 58