Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript, possible to pass undeclared method parameters without eval?

Tags:

javascript

Ok, difficult to understand from the title only. Here is an example. I want a function to refer to a variable that is "injected" automagically, ie:

function abc() {
   console.log(myVariable);
}

I have tried with:

with({myVariable: "value"}) { abc() } 

but this doesn't work unless abc is declared within the with block, ie:

with({myVariable: "value"}) { 

    function abc() {
       console.log(myVariable);
    }

    abc();  // This will work

}

So the last piece will work, but is it possible to fake the with statement, or do I have to force the developers to declare their function calls in a with statement?

Basically the call I want to do is:

doSomething({myVariable: "value"}, function() {
    console.log(myVariable);
});

Ofcourse, I am aware I could pass this is a one parameter object, but that is not what I am trying to do:

doSomething({myVariable: "value"}, function(M) {
    console.log(M.myVariable);
});

Further more, I am trying to avoid using eval:

with({myVariable: "value"}) { 

    eval(abc.toString())(); // Will also work

}

Is this not supported at at all beyond eval in Javascript?

like image 235
mjs Avatar asked Jul 17 '13 00:07

mjs


1 Answers

JavaScript does not provide any straightforward way to achieve the syntax you're looking for. The only way to inject a variable into a Lexical Environment is by using eval (or the very similar Function constructor). Some of the answers to this question suggest this. Some other answers suggest using global variables as a workaround. Each of those solutions have their own caveats, though.

Other than that, your only option is to use a different syntax. The closest you can get to your original syntax is passing a parameter from doSomething to the callback, as Aadit M Shah suggested. Yes, I am aware you said you don't want to do that, but it's either that or an ugly hack...


Original answer (written when I didn't fully understand the question)

Maybe what you're looking for is a closure? Something like this:

var myVariable = "value";
function doSomething() {
    console.log(myVariable);
};
doSomething(); // logs "value"

Or maybe this?

function createClosure(myVariable) {
    return function() {
        console.log(myVariable);
    };
}
var closure = createClosure("value");
closure(); // logs "value"

Or even:

var closure = function(myVariable) {
    return function() {
        console.log(myVariable);
    };
}("value");
closure(); // logs "value"
like image 99
bfavaretto Avatar answered Sep 28 '22 12:09

bfavaretto