2

I'm trying to access a variable local to a function in an external function as a free variable.

This is what I'm trying to achieve:

function try_evaluate() {
    var i = 0;
    show_r("i <= 10");
}

function show_r(expression) {
    if (eval(expression)) {
        i++;
        show_r(expression);
    } else alert(eval(expression));
}

I get an error because the variable i is not defined in the scope of show_r. Making i a global variable works but I need i to be a local variable.

Aadit M Shah
  • 72,912
  • 30
  • 168
  • 299
Samuel BR
  • 51
  • 1

5 Answers5

2

With var i, that variable is only accessible in the scope of the function in which it is defined. An anonymous function in the same scope does have access to it, but a call to a function defined externally does not have access. Instead, you need to pass the variable or define it in a scope that is available to both contexts (e.g. the global scope, but I'm not suggesting you use that).

I'd also be extremely wary about what you're trying to do specifically. If you have to use eval to do something, it's probably the wrong thing.

Explosion Pills
  • 188,624
  • 52
  • 326
  • 405
  • Hi, I try to emulate a while statement, then the expression can change, because this I need eval to evaluate them. Thanks for answer! – Samuel BR Mar 12 '13 at 02:47
1
function try_evaluate(){
    var i = 0;
    show_r(i);
}
function show_r(x){
    //console.log(eval.expression);
    if (x<=10){
       x++;
        console.log(x);
        show_r(x);
    } else {
        console.log(false);
    }       
}`

Why are you doing eval? I think you can achieve what you intend to do with above code.

smk
  • 5,340
  • 5
  • 27
  • 41
  • I try to emulate a while statement, then, the consumer can do something like: show_r('i > 9') or show_r('i != 3') or things like that, this is because I need eval(). Thanks for answer! – Samuel BR Mar 12 '13 at 02:43
  • So in true functional sense, you could write a function that takes in two params, x , y and the operator and do the evaluation there. – smk Mar 12 '13 at 16:56
1

This seems like the kind of thing dynamic scoping in JavaScript is useful for. See this StackOverflow thread: Is it possible to achieve dynamic scoping in JavaScript without resorting to eval?

This is what I would do:

function try_evaluate() {
    var i = 0;
    var show_r_dynamic = eval("(" + show_r + ")");
    show_r_dynamic("i <= 10");
}

Everything else remains the same:

function show_r(expression) {
    if (eval(expression)) {
        i++;
        show_r(expression);
    } else alert(eval(expression));
}

You can see the demo here: http://jsfiddle.net/53Qsu/

Community
  • 1
  • 1
Aadit M Shah
  • 72,912
  • 30
  • 168
  • 299
0

This will work better:

function try_evaluate(){
    var i = 0;
    show_r('$ <= 10', i);
    show_r('false', i);
}

function show_r(expression, i){
    if (eval(expression.replace('$', i))){
        i += 1
        show_r(expression, i);
    } else {
        alert(eval(expression.replace('$', i)));
    }       
}
Lydon
  • 2,942
  • 4
  • 25
  • 29
  • Hi, this don't work for my situation because the expression to evaluate can change, how I say, I try to emulate a while statement, then the consumer can do something: show_r('a <= 3') or show_r('true') or things like that. Thanks for answer! – Samuel BR Mar 12 '13 at 02:45
  • If you want the evaluation to be dynamic, use a dummy character as I have shown above and then replace it in the show_r function. This way you can pass in 'true' or 'false' as well. – Lydon Mar 12 '13 at 03:16
0

You should add i t the string but like this. Pass it as a paremeter and integrate it in the expression.

function try_evaluate() {
   var i = 0;
   show_r(i," <= 10");
}

function show_r(i,expression) {
    if (eval(i+expression)) {
        i++;
        show_r(i+expression);
    } else alert(eval(i+expression));
 }

or you could try replacing it in the expression to allow for && expresions with multiple i's

function try_evaluate() {
   var i = 0;
   show_r(i,"i <= 10");
}

function show_r(i,expression) {
    if (eval(expression.replace("i",i)) {
        i++;
        show_r(expression.replace("i",i));
    } else alert(eval(expression.replace("i",i)));
 }
zardilior
  • 2,810
  • 25
  • 30