2

is it possible to call inner function dynamically(by it's name)?

e.g.

function a(){
    function b(){..}
    var funcName = "b";
    //calling the function b somehow using funcName
}

I know it's possible by using eval, but I rather not using eval, if b was global function I could use window[funcName] or global[funcName]...

4 Answers 4

2

Sounds like you want to access b through its name ("b") magically, without recording the name b in a separate structure.

You are correct that global variables are properties of the global object, generally accessed through the identifier window in web environments. It's fun how that works actually, as window is a property of the global object pointing to itself, but, that is off topic.

Local variables are properties of an object, too -- the call object. This object exists temporarily during the call. If you could get to the call object directly, then you would be able to say something like theCallObject[funcName], because the nested function is still a local variable, although hoisted. Alas, this object is not directly accessible, so you basically have to revert to the techniques shown in the earlier answers.

Here is an SO question with info: How to output call object in javascript?.

I suppose it is possible to write a JS engine with an extension permitting access to the call object, much like Mozilla gave us the non-standard __proto__.

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

3 Comments

Because I didn't think this was very clear: while local variables are stored in an object -- of sorts -- this detail is not exposed in JavaScript and although is talked about in such in the specification it may be implemented differently -- for optimization and closure minimizing, for instance -- due to not being exposed. (The only exception is arguments[n], where n is a numeric index, which are function parameters, not variables).
I'll buy that, @pst. That fact that the call object is discussed in the spec does not mean it has to actually exist in actual implementation as a JavaScript object. It exists to help describe the semantics. Fair enough. Totally. I'll stand by my remark that if access to it were granted by some implementation then one would be able to do what the OP wanted. As it stands now, there is no such magic, I believe. +1 for your technical comment.
It would indeed be possible in that case ;-) Python has the ill-mentioned locals() function which can do just that which is proposed (with the warning that the python run-time makes no guarantee that changes will be propagated.) On another note the linked SO question/answer mixes up the "call object" -- I use quotes because it is used in a different context in post and answers -- and the activation object. (The activation object is not this.)
1

Well, if you can declare it differently, and it's not so hard:

function a(){
    this.b = function() {...};

    // dynamic access
    var funcName = "b";
    this[funcName]();

    // still need static access?
    var b = this.b;
    b();
}

You can mix it up, of course. But Functions are just objects (both a and b), so they can be assigned, moved around, and even have instance members.

1 Comment

That will work differently depending on the invocation context of a (e.g. what this points to) so I would not recommend that construct.
1

A variation on OverZealous's answer that does not muck with this:

function a(){
    function b(){..}
    var internalFuncs = {"b": b}
    var funcName = "b"
    internalFuncs[funcName]()
}

Happy coding.

Comments

1

Another approach:

var a = (function() {
    return {
        b: function() { alert("b"); },
        c: function() { alert("c"); },
        d: function() { alert("d"); }
    }
})();

a["b"]();

Fiddle: http://jsfiddle.net/raSKW/

Comments

Your Answer

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