Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

javascript: access function in closure [closed]

I have the name of a function in a variable, but everything is within a closure. With this variable I want to call the function, something like this

(function(func) {
      this[func]() ;         // doesn't work

      function bar() {}
      function foo() {}
})('bar') ;

Is something like this possible or should I, for example, add the functions to a variable, like

(function(func) {        
      var ns = {
          bar: function() {},
          foo: function() {}
      };

      ns[func]() ;         // OK
})('bar') ;
like image 604
Jeanluca Scaljeri Avatar asked May 23 '13 19:05

Jeanluca Scaljeri


3 Answers

In my experience, putting a function inside a closure is one way of declaring it "private" - such that nothing outside can access it. Furthermore, it's worth looking at the way code is minified:

Before:

(function() {
    function privateFn(var1, var2) {
        //TODO
    }
    return {
        publicFn: function() { }
    }
})();

After:

(function() {
    function _a(_0, _1) {

    }
    return {
        publicFn: function() { }
    }
})();

Notice how privateFn doesn't really exist anymore? The minifier knows, by definition of the language, that nothing can access that function outside - by name, or otherwise. You seem to want to make one of your functions public.

like image 153
Katana314 Avatar answered Oct 22 '22 06:10

Katana314


Variables and functions declared in the current lexical scope cannot be accessed by name using [] syntax - only property keys (per your second example) can be looked up dynamically based on the contents of another variable.

The only way around this is to resort to eval, which is almost never a good idea.

An exception applies for variables and functions declared in the global scope - those are actually properties of window.

like image 25
Alnitak Avatar answered Oct 22 '22 05:10

Alnitak


Something like this:

(new function() {
    this.a = function(x) {
        document.getElementById('out').innerHTML += x;
    }
})['a']('boom.');

http://jsfiddle.net/CT4du/1/

A closure keeps everything private. And normally, this in a closure just refers to the window. But, you can "publicize" items in a "closure" without polluting the global space by turning it into an anonymous object first. This allows you to make one and only one method call on the object before it vanishes ...

You can do normal object things, like use private, lexical variables and expose only the methods you want exposed.

(new function() {

    var a = function(x) { document.getElementById('out').innerHTML += x; }
    var b = function() { a(d); }
    var c = function() { /* ... */ }
    var d = "whatever";

    // expose two of them .. 
    this.a = a;
    this.b = b;

})['a']('boom.');
like image 37
svidgen Avatar answered Oct 22 '22 05:10

svidgen