This question is more on javascript principle.
function done(){ console.log('done defined with `function done(){ ...`'); }
var done = function(){ console.log('done defined with `var done = ...`'); }
done = function(){ console.log('without `var`, just `done = ...`'); }
If defined right inside <script>
tags, will they all do the same thing, right?
But if I place them in a closure (function(){
function definintion goes here }())
will any of these three types override either the globally defined function done() or any other done() functions that are defined inside their respective closures?
If the question above doesn't make sense, here's to rephrasing;
- is the following code supposed to do the same thing in any JS runtime?
eval
-ing code anywhere executes that particular code within the context or the global scope?
how can a setTimeout
call be configured so that the code between its "quotes" executes to inside the scope where that particular setTimeout
has been called (please see second timeout inside for
below)? I mean is there any other way besides defining window.blabla functions and telling them to delete themselves after they run?
function done(d){ console.log('cha cha cha: '+d); }
setTimeout( function(){ done(2); }, 3500 );
for(i=0; i<10; i++){
(function(){
done = function(x){ console.log('done #'+i+' sais: '+x); }
setTimeout(function(){ done(i*2); },2500);
setTimeout(function(){ done(i*2); }.toString()+'(); ',2500);
}());
}
For the initial question on general behaviour:
var done =
and function done
do basicaly the same thing. They will shadow the outer definition in the inner scope but they will not replace it on the outer scope.
done =
will set the corresponding done
variable in scope or will create a global variable if such a variable does not exist and the program is not running in strict mode.
At a global level, outside any function, var done =
and done =
should work the same, but they work differently in IE if you try to use the variable in another script tag (stick to var =
- its better anyway).
As for the very evil setTimeout and eval questions:
Yes, I guess this kind of stuff should be standardized enough to work the same everywhere. I would still test it anyway. (Or you could use a different solution, given how evil eval is)
eval runs code in the current scope (using deep black magic to do so). If you want to run code on the global scope you can use new Function
instead.
In order to have the settimeout run the string in the curent scope you can add the eval yourself:
var done = function(d){ console.log('outer done', d); };
(function(){
var done = function(x){ console.log('inner done', x); };
setTimeout(function(){ done(1); }, 200); //inner done
setTimeout('done(2)', 400); //outer done
setTimeout(function(){ eval('done(3)'); }, 600); //inner done
}());
Once again, why are you eval-ing things in the setTimeouts? This all sounds profoundly evil!
There are differences between var done
and done
, because the latter implicates window.done
and can be delete
d therefore.
The statement done = foobar;
will overwrite the next "done" variable in the scope chain. If there is a local var
, it changes that, if there is a global one, it will overwrite that one, anf if not it will create a new global one.
All these will not affect any private variables in other scopes (closures).
One note on your first block. When you give a function a name as you have in the first line, that function name is parsed at compile time and available anywhere within the scope. If you simply assign a function to a variable, then that function (i.e., variable) is only available at runtime after the definition, even if you give it a name.
For example:
// this is valid
foo();
function foo(){ console.log("foo"); }
// this throws an error...
bar();
var bar = function (){ console.log("bar"); };
// ...and so does this...
baz();
var bat = function baz(){ console.log("bazbat"); };
// ...and this!
baz();