0

I am trying to execute a function at a different scope than where it is defined. I need to get the variables available in the runtime scope available to the functions context.

A sample code can be like

var k = function () { alert(x); };

(function () {

    var x = 100;
    k();

})();

Its not possible for function k to access x which is in the scope where it is run.

Possible work arounds that I have are:

  1. inject x as a parameter to function
  2. use eval like

    var k = "function () { alert(x); }";
    
    (function () {
    
        var x = 100;
        var m = eval("("+k+")");//prints 100
        m();
    
    })();
    //But this same work around wont work if I use k = "alert(x);" and 
    //define m = new Function(k);
    
  3. bind x as the this context for the function and do alert(this).

If i rule out the above 3 options, are there any other ways of approaching this problem? Is there a way I can inject variables into a function scope in runtime, just like call,apply and bind does for this ?

Mithun Satheesh
  • 27,240
  • 14
  • 77
  • 101
  • 1
    No, if you want the variables accessible in the function, you pass them as arguments. – adeneo Jan 13 '15 at 07:31
  • 1
    Can you explain what problem you're really trying to solve since passing `x` as an argument is the obvious solution here? – jfriend00 Jan 13 '15 at 07:38
  • @jfriend00 : I am trying to write a library where the user will be able to write functions to decide the flow. Inside the functions he can use some private functions that the library supports. May be like `stop()`,`rework()` etc. Passing them as arguments dint seem good at that point. – Mithun Satheesh Jan 13 '15 at 07:46
  • possible duplicate of [Is it possible to achieve dynamic scoping in JavaScript without resorting to eval?](http://stackoverflow.com/questions/10060857/is-it-possible-to-achieve-dynamic-scoping-in-javascript-without-resorting-to-eva) – tmadsen Jan 13 '15 at 07:48
  • 1
    If you don't want these functions available anywhere else, then pass a single namespace argument to their function (as the first argument) and have all your library functions be properties of that namespace object. If your functions can be globally accessible, then just put them on a single global namespace object and have the user use them from the global namespace object such as `myLib.stop()` and `myLib.rework()`. Or make `this` be your namespace object so they can call them as `this.stop()` and `this.rework()`. – jfriend00 Jan 13 '15 at 07:48
  • @jfriend00 : I got your point and its solves my problem. But what if I resort to the eval option I mention in the question, just to avoid even injecting the common namespace and just use readily readable functions? Just curious to know what you think of it. And that indeed was the purpose of this question :) – Mithun Satheesh Jan 13 '15 at 07:57
  • 1
    I tend to avoid `eval()` entirely, but perhaps it has a place in the unique application you have. I'm not really sure what the pros/cons of using it in that context are. I'd suggest you read these two references: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval and https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode to understand things to be aware of when using `eval()`. – jfriend00 Jan 13 '15 at 21:54

1 Answers1

1

I see that in your function it's OK to declare a variable and not call k directly.

Is this suitable for you?

var o = 
{
    x : 50,
    k : function() { alert(this.x); }
}

o.k();

(function () {

    this.x = 100;
    var f = o.k;
    f();
    o.k();

})();
B0Andrew
  • 1,725
  • 13
  • 19
  • nice try. But this is actually doing the 3rd option i mentioned internally. – Mithun Satheesh Jan 13 '15 at 09:37
  • But what if I resort to the eval option I mention in the question, just to avoid even using the `this` and just use readily readable functions? Just curious to know what you think of it. And that indeed was the purpose of this question :) – Mithun Satheesh Jan 13 '15 at 09:39