19

For the following script, how can I write a function that returns all of the script's functions as an array? I'd like to return an array of the functions defined in the script so that I can print a summary of every function that is defined in the script.

    function getAllFunctions(){ //this is the function I'm trying to write
        //return all the functions that are defined in the script where this
        //function is defined.
        //In this case, it would return this array of functions [foo, bar, baz,
        //getAllFunctions], since these are the functions that are defined in this
        //script.
    }

    function foo(){
        //method body goes here
    }

    function bar(){
        //method body goes here
    }

    function baz(){
        //method body goes here
    }
Anderson Green
  • 30,230
  • 67
  • 195
  • 328
  • To clarify, getAllFunctions() should only return the functions that are defined in the script itself, and nothing else. – Anderson Green Jul 01 '12 at 03:58
  • I clarified the original question so that the question is no longer ambiguous. – Anderson Green Jul 01 '12 at 04:00
  • See this post http://stackoverflow.com/questions/493833/list-of-global-user-defined-functions-in-javascript – anazimok Jul 01 '12 at 04:01
  • [Already been asked.](http://stackoverflow.com/questions/493833/list-of-global-user-defined-functions-in-javascript?lq=1) – Jared Farrish Jul 01 '12 at 04:01
  • 1
    I'm not sure if that's an exact duplicate, since the asker of that question only wanted to filter out "native functions" as opposed to "user-defined functions." That question is close to what I'm looking for, but the question is not an exact match for my question. – Anderson Green Jul 01 '12 at 04:05
  • Fortunately, there's dozens, maybe hundreds?, of other "Javascript Reflection" queries. Look at the long **Related** list to the right. They can't all be rejected as insufficient. – Jared Farrish Jul 01 '12 at 04:11
  • 1
    What exactly is the purpose of this function, are you unable to define the functions on their own object - which would make detection of them far easier. I'm failing to understand the purpose behind the "getAllFunctions" function. – Brandon Buck Jul 01 '12 at 05:53
  • I edited the question slightly to explain the use case. – Anderson Green Jul 01 '12 at 14:58
  • Also, this question appears to be a duplicate: http://stackoverflow.com/questions/2418388/how-can-get-a-list-of-the-functions-in-a-javascript-file – Anderson Green Jul 02 '12 at 00:31

4 Answers4

16

Here is a function that will return all functions defined in the document, what it does is it iterates through all objects/elements/functions and displays only those whose type is "function".

function getAllFunctions(){ 
        var allfunctions=[];
          for ( var i in window) {
        if((typeof window[i]).toString()=="function"){
            allfunctions.push(window[i].name);
          }
       }
    }

​ Here is a jsFiddle working demo.

​Add the function at the last and this snippet getAllFunctions().slice(48, -4) will just return the user defined functions in Vivaldi.

Smart Manoj
  • 5,230
  • 4
  • 34
  • 59
Ashwin Singh
  • 7,197
  • 4
  • 36
  • 55
  • 2
    The problem with this is that it will catch all functions defined in previous scripts that were attached to window. And it's a very bad idea to toss things onto window in the first place. – Brandon Buck Jul 01 '12 at 05:51
  • 4
    Adding `&&window[i].toString().indexOf("native")==-1` to the if fixes that. – Aaron Gillion Jan 12 '16 at 10:05
  • Should this still work in today's browsers? I paste it into DevTools Console and it returns 'undefined' – golimar Oct 29 '20 at 15:47
  • 1
    @golimar It returns `undefined` because it doesn't have a `return` statement. I tested it again [here](https://jsfiddle.net/4gfz158x/), and it still generates a list of function names. – Anderson Green Jul 24 '21 at 17:07
13

Declare it in a pseudo namespace, for example like this:

   var MyNamespace = function(){
    function getAllFunctions(){ 
      var myfunctions = [];
      for (var l in this){
        if (this.hasOwnProperty(l) && 
            this[l] instanceof Function &&
            !/myfunctions/i.test(l)){
          myfunctions.push(this[l]);
        }
      }
      return myfunctions;
     }

     function foo(){
        //method body goes here
     }

     function bar(){
         //method body goes here
     }

     function baz(){
         //method body goes here
     }
     return { getAllFunctions: getAllFunctions
             ,foo: foo
             ,bar: bar
             ,baz: baz }; 
    }();
    //usage
    var allfns = MyNamespace.getAllFunctions();
    //=> allfns is now an array of functions. 
    //   You can run allfns[0]() for example
KooiInc
  • 119,216
  • 31
  • 141
  • 177
  • 1
    +1 for rightly capturing functions, I believe I had seen similar way in John Resig's **Secrets of JavaScript Ninja** book – Blaster Jul 01 '12 at 06:15
  • 3
    It works, but this seems a bit redundant: return { getAllFunctions: getAllFunctions ,foo: foo ,bar: bar ,baz: baz }; Is it possible to do this without hard-coding the name of each function? – Anderson Green Jul 02 '12 at 20:31
  • @Anderson: you need a reference to the functions themselves, but it doesn't have to be public. Alternatively you can assign an object like `var fns = {foo:foo,bar:bar ...}` variable within `MyNamespae` and query that using `getAllFunctions`. Than you only have to expose `getAllFunctions` -> `return {getAllfunctions:getAllfunctions};` – KooiInc Jul 03 '12 at 06:33
  • If I use the Angular.js annotate function here: https://github.com/angular/angular.js/blob/dde1b2949727c297e214c99960141bfad438d7a4/src/auto/injector.js#L63-L96 `annotate(allfns[0])` I get a `[]` of parameters, while it works calling the actual function `annotate(MyNamespace. foo)`. Why? – loretoparisi Mar 16 '16 at 10:58
2

More than 1 hour wasted on this.

This is read .js file from node.js

1.Install a node module:

npm i esprima

2.Assume you have a function func1 declared like below, in a file a.js in current directory:

var func1 = function (str1, str2) {
    //
};

3.And you would like to get name of it, that is func1, the code is below:

const fs = require("fs");
const esprima = require("esprima");

let file = fs.readFileSync("./a.js", "utf8");

let tree = esprima.parseScript(file);
tree.body.forEach((el) => {
    if (el.type == "VariableDeclaration") {
        // console.log(el);
        console.log(el.declarations);
        console.log(el.declarations[0].id);
        console.log(el.declarations[0].id.name);
    }
});

4.You can also get other details like parameters str1, str2, etc, uncomment the console.log(el) line to see other details.

5.You can put both above code parts in one file, to get the details of current file (a.js).

Manohar Reddy Poreddy
  • 25,399
  • 9
  • 157
  • 140
1

function foo(){/*SAMPLE*/}
function bar(){/*SAMPLE*/}
function www_WHAK_com(){/*SAMPLE*/}

for(var i in this) {
 if((typeof this[i]).toString()=="function"&&this[i].toString().indexOf("native")==-1){
  document.write('<li>'+this[i].name+"</li>")
 }
}
Dave Brown
  • 923
  • 9
  • 6