Reputation: 10496
function a(callback) {
var something = 10;
callback(something);
}
a(function(blabla) {
console.log(blabla); // output 10
});
Ok i dont have problem understanding this code.
I know that "something" is local to function a
and but in the sense of closures and fact that execution context is created when function is called i expected following to work also:
function a(callback) {
var something = 10;
callback();
}
a(function() {
console.log(something);
});
So what happened exactly (why second example don't work)?
Obviously everything is garbage collected and not accessible in body of callback function.
Upvotes: 4
Views: 717
Reputation: 153
Short answer:
The closure created by the callback in the second example, will look for the global variable something
which does not exist.
Vs. the first example creates a closure around the variable something
within function a
. If the value of something
is mutated, calling a
again will produce a different value.
Consider the following different ways to pass callback functions:
var something = "Global something";
function a(callback) {
var something = "Local something";
callback(something);
}
a( console.log ); // "Local something"
As defined, console.log()
will accept the something
passed by function a
as its first argument and prints it out to the screen. Closure happens on the local variable.
a( function() {console.log(something)} ); //"Global something"
When you define a function inline it creates its own scope, and references a local variable something
.
The something
passed by function a
gets dropped as the inline function did not catch it.
In some stricter languages it will throw an error, but JS does not.
The inline function tries to console.log
the local variable something
, which is not found. Searches global scope and finds "Global something" and prints it. No closure on the local variable.
a( function(x) {console.log(x)} ); //"Local something"
The inline function creates and references local variable x
.
But x
points to the something
variable passed by function a
, which in turn which points to "Local something", which gets printed. Closure on the local variable.
Upvotes: 0
Reputation: 173662
A function can only reference variables that are declared in either:
In other words, the calling scope is not taken into account and so something
is considered undefined.
Upvotes: 2
Reputation: 3272
In your first example:-
function a(callback) {
var something = 10;
callback(something);
}
a(function(blabla) {
console.log(blabla); // output 10
});
blabla is a variable which is available to the anonymous function passed as parameter to a. So something is passed to callback function as function parameter and is hence available to function under name blabla.
But in second example:-
function a(callback) {
var something = 10;
callback();
}
a(function() {
console.log(something);
});
something is unknown to the function as its not a global variable/ is not a function parameter.
So this is a js error as you are trying to access an undefined variable.
So scope of something is limited to the function a and is not available to the callback function
Upvotes: 1
Reputation: 437904
In the second example, the local variable something
is not accessible in the body of your callback not because it's garbage collected, but simply because it is out of scope.
Consider this counter-example:
function a(callback) {
callback();
}
var something = 10;
a(function() {
console.log(something);
});
Here something
is in scope at the time the body of the callback is defined so you can reference it. Doing so creates a closure.
Also consider this one:
function foo() {
var xyz = 1;
bar();
}
function bar() {
console.log(xyz);
}
This is functionally the same example as you have: foo
is a
and bar
is the anonymous function passed in as callback
.
Why should calling bar()
result in printing 1
here? That variable is locally scoped inside foo
, and bar
knows nothing about it.
Upvotes: 4
Reputation: 149108
In reading your question, it sounds to me like the primary confusion here is in why you can reference something
inside a
, but not inside the anonymous function provided to a
.
The variable something
is defined within the context of the function a
, not within the anonymous function. So when you reference something
inside the anonymous function, it actually references an implicit global variable, which in this case is not defined. The fact that the anonymous function is placed within the parameter list of a call to a
makes no difference.
Perhaps it would be more clear if you realize that the second snippet is roughly equivalent to:
function a(callback) {
var something = 10;
callback();
}
function b() {
console.log(something);
}
a(b);
So you can see clearly these are two completely unrelated functions, with their own scopes.
Upvotes: 1