1

I've read some guides on scope in JS, but I don't quite get what's going on here.

This does work:

var b = 6;
function a(){
    alert(b);
}
a(); //alerts 6

However, this makes Firebug say "x is not defined"

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

function funcA(anonymous){
    var x = 10;
    anonymous();
}

funcA(funcB);

So why doesn't the free x variable in funcB get binded to the x declared to be 10 in the first line of funcA?

Thanks

user3391564
  • 576
  • 1
  • 5
  • 16
  • `var` declares a **local** variable. See http://stackoverflow.com/questions/111102/how-do-javascript-closures-work/111200#111200 – elclanrs Apr 03 '14 at 23:43

2 Answers2

1

You can't do that because var declares a local variable, only visible within the scope of the function where it is declared.

Whatever is inside the body of funcB doesn't see what is in the body of funcA, you have to be explicit (pass arguments), or declare funcB inside funcA to close over x (a closure).

So what you can do is make funcB take x as an argument:

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

function funcA(fn) {
  var x = 10;
  fn(x);
}

funcA(funcB);
elclanrs
  • 92,861
  • 21
  • 134
  • 171
  • But isn't the call to anonymous within the scope in which x is declared, i.e. in funcA? I know I can use arguments to functions--this is just an experiment. – user3391564 Apr 03 '14 at 23:50
  • What was throwing me off was that I didn't know that free variables are bound during the creation of the function, _not_ the execution of the function. – user3391564 Apr 04 '14 at 00:01
  • @user3391564: JavaScript has lexical scope, not dynamic scope. – Felix Kling Apr 04 '14 at 00:09
1

Each function in JavaScript has its own Lexical Environment: a map between identifiers (names) used within it, and specific variables (and functions) that either exist (in the outer scopes) or will be created within the scope of this function.

The key point is that Lexical Environment for a given function is created at the moment this function is defined - not when it's executed.

At your second example, name x mentioned within funcB doesn't have anything to map to - there's no variable named x in its own scope or the parent (outer) scopes. Unlike the first example, where b can be mapped to a local variable named b, living in the same scope function a lives.

And of course, funcB cannot (and shouldn't) know about lexical environments of other functions, as it cannot (and shouldn't) know whether it will be called from within these functions - or not.

raina77ow
  • 103,633
  • 15
  • 192
  • 229