JavaScript function declaration and evaluation order -
why first 1 of these examples not work, other ones do?
// 1 - not work (function() { settimeout(somefunction1, 10); var somefunction1 = function() { alert('here1'); }; })(); // 2 (function() { settimeout(somefunction2, 10); function somefunction2() { alert('here2'); } })(); // 3 (function() { settimeout(function() { somefunction3(); }, 10); var somefunction3 = function() { alert('here3'); }; })(); // 4 (function() { settimeout(function() { somefunction4(); }, 10); function somefunction4() { alert('here4'); } })();
this neither scope problem nor closure problem. problem in understanding between declarations , expressions.
javascript code, since netscape's first version of javascript , microsoft's first copy of it, processed in 2 phases:
phase 1: compilation - in phase code compiled syntax tree (and bytecode or binary depending on engine).
phase 2: execution - parsed code interpreted.
the syntax function declaration is:
function name (arguments) {code}
arguments of course optional (code optional what's point of that?).
but javascript allows create functions using expressions. syntax function expressions similar function declarations except written in expression context. , expressions are:
- anything right of
=
sign (or:
on object literals). - anything in parentheses
()
. - parameters functions (this covered 2).
expressions unlike declarations processed in execution phase rather compilation phase. , because of order of expressions matter.
so, clarify:
// 1 (function() { settimeout(somefunction, 10); var somefunction = function() { alert('here1'); }; })();
phase 1: compilation. compiler sees variable somefunction
defined creates it. default variables created have value of undefined. note compiler cannot assign values yet @ point because values may need interpreter execute code return value assign. , @ stage not yet executing code.
phase 2: execution. interpreter sees want pass variable somefunction
settimeout. , does. unfortunately current value of somefunction
undefined.
// 2 (function() { settimeout(somefunction, 10); function somefunction() { alert('here2'); } })();
phase 1: compilation. compiler sees declaring function name somefunction , creates it.
phase 2: interpreter sees want pass somefunction
settimeout. , does. current value of somefunction
compiled function declaration.
// 3 (function() { settimeout(function() { somefunction(); }, 10); var somefunction = function() { alert('here3'); }; })();
phase 1: compilation. compiler sees have declared variable somefunction
, creates it. before, value undefined.
phase 2: execution. interpreter passes anonymous function settimeout executed later. in function sees you're using variable somefunction
creates closure variable. @ point value of somefunction
still undefined. sees assigning function somefunction
. @ point value of somefunction
no longer undefined. 1/100th of second later settimeout triggers , somefunction called. since value no longer undefined works.
case 4 version of case 2 bit of case 3 thrown in. @ point somefunction
passed settimeout exists due being declared.
additional clarification:
you may wonder why settimeout(somefunction, 10)
doesn't create closure between local copy of somefunction , 1 passed settimeout. answer function arguments in javascript always, always passed value if numbers or strings or reference else. settimeout not variable somefunction passed (which have meant closure being created) rather gets object somefunction refers (which in case function). used mechanism in javascript breaking closures (for example in loops).
Comments
Post a Comment