the "name" in the first version refers the global window.name
property*, and in the second example to the private var name through the closure. The window.name
property is optional and defaults to an empty string.
If this property wouldn't happen to exist your first example would throw a reference error.
The closure is created at the scope a function was declared, not at the point it got called and in the first example the function was declared inside the global scope, in the second inside the wrapper function scope.
window.name = "NoClosure";
(function(){
var name = "Closure";
arguments[0]();
})(function(){console.log(name);}); //>"NoClosure"
window.name = "NoClosure";
(function(){
var name = "Closure";
(function(){console.log(name);})(); //>"Closure"
})();
If you inspect the of the callback with console.dir()
, you can see that it has no closure, here a snippet if you want to test it yourself.
(function wrapper(){
var isPrivate = "A closure could see me";
console.dir(arguments[0]);
})(function callback(){});
Here is another experimental setup with 2 closures showing that function declared inside a call to a function are capable of getting a closure, but it will always be the closure of the scope of the function passing it, it can not access the scope of the function it was passed to as an argument and that later calls it as a callback.
(function outerScope(){
var outerVar = "in outer scope";
(function innerScope(cb){
var innerVar = "in inner scope";
cb();
})(function callback(){
console.log(
"outer:"+ typeof outerVar,
"inner:"+ typeof innerVar);
console.dir(arguments.callee);
})
})()
*source https://developer.mozilla.org/en-US/docs/Web/API/Window.name