1

Because callbacks behave as if they are actually placed inside a function, they are in practice closures: they can access the containing function’s variables and parameters, and even the variables from the global scope link. Right? But if I do:

function fullName(firstName, lastName, callback){
 var f_scope = "X";
  console.log("My name is " + firstName + " " + lastName);
  callback(lastName);
}

var greeting = function(ln){
  console.log('Welcome Mr. ' + ln);
  console.log(f_scope);//<<---error

};

fullName("Jackie", "Chan", greeting);

In other hand if greeting was inside of fullName the error will not happen. So callbacks are not 100% like if they are placed inside of a function? Right?

carduh
  • 529
  • 1
  • 4
  • 13
  • 3
    So what is your question ? – Mulan Dec 10 '15 at 00:22
  • 3
    "So callbacks are not 100% like if they are placed inside of a function." --- callbacks 100% like they were **not** placed inside of a function. Your whole question (there is no one actually though) starts with a wrong assumption. Everything else is based on it and is incorrect as well. – zerkms Dec 10 '15 at 00:23
  • 8
    Scoping is **static**. What matters is the context in which the function is defined, not the context in which it's called. It's called *lexical scoping* because what matters is the textual context of the function definition itself. When references to the function are passed around at runtime, they retain access to the *lexical* - source code - context, but it's not modified dynamically based on the environment when the function is called. – Pointy Dec 10 '15 at 00:23
  • 4
    Closures and scope are confusing to newbies, I recommend you spend some time reading about them. http://stackoverflow.com/questions/111102/how-do-javascript-closures-work http://stackoverflow.com/questions/500431/what-is-the-scope-of-variables-in-javascript – jered Dec 10 '15 at 00:26

4 Answers4

4

they can access the containing function’s variables and parameters

Lexically containing. They can access the variables from the scope in which the function is defined, not those from the scope where it is called. Functions in JS do form lexical closures, there is no dynamic scoping.

That f_scope variable is neither a global variable nor declared in a function that contains greeting.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
1

Because callbacks behave as if they are actually placed inside a function

Callbacks defined inside a function behave as if they were defined inside a function. Callbacks defined outside a function behave as if they were defined outside a function.

they are in practice closures

They are closures, in theory and in practice. What differs is what they close over.

var x = 1;
function externalCallback() {
  // closes over x, someFunction, externalCallback
}
function someFunction() {
  var y = 2;
  var internalCallback = function() {
    // closes over x, someFunction, externalCallback, internalCallback, y
  }
  setTimeout(externalCallback, 0);
  setTimeout(internalCallback, 0);
}
Amadan
  • 191,408
  • 23
  • 240
  • 301
1

Take a look at this example:

function callback_caller(callback) {
    var x = 7;
    callback();
}

function func1() {
    var y = 9;
    function inner_func() {
        // console.log('x', x); // <-- this would not work
        console.log('y', y);    // <-- this is ok
    }
    return inner_func;
}

var callback = func1();
callback_caller(callback); // prints: y 9

At the time when inner_func gets called, func1, which contains variable y is long gone, but still inner_func can access it. That is because y is in the closure.

On the other hand, x has nothing to do with inner_func and is never available there.

zvone
  • 18,045
  • 3
  • 49
  • 77
0

fullName is at root context, so it can see itself and "greeting".

fullName then creates "f_scope" which is only visible inside fullName.

root context calls fullName with firstName, lastName, callback. The firstName and lastName are only available inside of the fullName context, as params are local/private variables of the function.

fullName then calls callback, which accepts a param, ln, which happens to be the lastName param/variable in fullName, but this is passed as a param, not access directly.

f_scope is private to fullName, therefore, you cannot call it inside greeting, you can pass it to greeting if you make it a parameter of the function.

joseeight
  • 904
  • 7
  • 10