0

I'm not sure if this is possible or not, but I drop here a sample of what I would like to achieve:

(function() {
   function A() {}
   function B() {}

   var funcs = /* how do I get both A and B programatically? */;
})();

Both A and B aren't accessible by accessing window and this inside of the self-invoked function.

I know I can add properties A and B to this inside the self-invoked function and this solves the issue, but I was wondering if there's a way to retrieve them with named functions.

Update

I believe that the issue is very clear: I wanted to know if I can get scoped named functions without explictly using the module pattern.

At the end of the day, I'm looking to validate that I'm missing nothing and there's no way to programatically obtain syntactically-scoped named functions.

8
  • What are you trying to do? Assign A and B to funcs? Commented Mar 25, 2015 at 13:58
  • @thefourtheye I want to retrieve them like a collection of functions Commented Mar 25, 2015 at 14:00
  • @FSou1 What if I don't know the names and I want to iterate all functions within the whole scope? :D Commented Mar 25, 2015 at 14:01
  • NOTE: I'm going to check answers/comments in 5 hours!! Thanks in advance ;) Commented Mar 25, 2015 at 14:01
  • 2
    It seems to me that this is a XY problem. Why would you want to do that? Commented Mar 25, 2015 at 14:07

3 Answers 3

1

You can't. See here.

Every execution context has associated with it a variable object. Variables and functions declared in the source text are added as properties of the variable object.

You don't get access to the variable object.

Sign up to request clarification or add additional context in comments.

1 Comment

This is the right answer to my question. This is why I can't understand the close votes and downvotes and XY problem things... I use module pattern every day, and I was looking to validate that JS still doesn't support getting parsed functions (not anonymous functions) because I usually use my spare time to perform my own R&D about how I would improve how current frameworks implement some features. Thank you!
1

If you're looking for something like get_defined_vars in php or locals in python, i.e. a function that returns all names defined in a local scope, there's no such thing in javascript, nor is it possible to implement it in any way (short of getting function source code as a string and parsing it).

Just to show you how ugly it can get:

function get_funcs(fn) {
    return fn.toString().match(/function\s+\w+/g).map(function(x) {
        return x.split(" ").pop();
    });
}

(function() {
    function A() { document.write('I am A<br>'); }
    function B() { document.write('I am B<br>'); }

    get_funcs(arguments.callee).map(function(f) {
        eval(f).call();
    });

})();

3 Comments

Yeah, we can also use Esprima parser, but well, I wanted to validate if it was any other way to do so without parsing. Thank you for your effort. BTW, I'm not a PHP/Python developer so I ignore that these languages implement something like this...
@MatíasFidemraizer: SO is used by millions of people, and information that isn't immediately useful for you might be valuable for someone else.
Absolutely, I know it
0

At this time, JavaScript provides no standard way to do this. It may be possible to leverage the debugging functions of the various JavaScript engines to achieve a similar effect, but I don't know how to do this on any particular engine (or if they even let you do it from "inside"), and any solution found for one engine probably wouldn't be portable to any other engines.

What you can do is collect these functions into an Object, and then iterate over that as a collection of functions. Your example code might translate into something like this:

var myModule = (function () {
    var exports = {};

    // Define your functions
    function A() {};
    function B() {};

    // Collect the functions you want to be part of the collection
    exports.A = A;
    exports.B = B;
    return exports;
}());

You could do it a bit more succinctly as:

var myModule = (function () {
    var exports = {};

    exports.A = function () {};
    exports.B = function () {};

    return exports;
}());

This is known as the Module pattern in the JavaScript world. The term has a broader meaning in more general computer science, but in the JavaScript community it usually means this specific way of implementing the more general pattern (as opposed to, say, CommonJS or AMD). Either way, because this implementation returns a plain Object, you can iterate over it the same way you'd iterate over any other.

You should also investigate both the CommonJS and AMD module systems. If either one would fit what you're trying to do, they could save you a lot of time.

2 Comments

Thank you for this, but as I stated in my question, I know I can go the module pattern way. An answer like "there's no way to do it" is enough!!
The stuff you mentioned in your question seemed more like registering the functions as globals (or rather, making them properties of the global object), which is why I got confused.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.