ecmascript 5 - Where is the immutable binding record of the identifier in a named function expression stored in JavaScript? -
recently ran interesting facts named function expressions (nfe). understand function name of nfe can accessed within function body, makes recursion more convenient , saves arguments.callee. , function name not available outside function body. example,
var foo = function bar() { console.log(typeof bar); }; typeof foo; // 'function' typeof bar; // 'undefined', inaccessible outside nfe foo(); // 'function', accessible inside nfe this well-documented feature, , kangax has wonderful post nfe , mentioned phenomenon there. surprises me function name of nfe cannot re-associated other values in function body. example,
(function foo() { foo = 5; alert(foo); })(); // alert function code instead of 5 in above example, tried rebind identifier foo value 5. fails! , turned es5 spec , found immutable binding record created , added environment records of lexical environment when nfe created.
the problem is, when nfe refers own function name inside function body, name resolved free variable. in above example, foo referred inside nfe, neither formal parameter nor local variable of function. it's free variable , binding record can resolved through [[scope]] property of nfe.
so consider this, if have identifier same name in outer scope, there seems conflict. example,
var foo = 1; (function foo() { alert(foo); })(); // alert function code rather 1 alert(foo); // 1 when execute nfe, free variable foo resolved function associated to. when control exits nfe context, foo resolved local variable in outer scope.
so question follows:
- where immutable binding record of function name stored?
- how come function name
foooutweighvar foo = 1when resolved inside nfe? binding records stored in same lexical environment? if so, how? - what's behind phenomenon function name
fooaccessible inside invisible outside?
can shed light on es5 spec? don't find discussion online.
where immutable binding record of function name stored?
in lexical environment record cannot see :-)
how come function name
foooutweighvar foo = 1when resolved inside nfe?
in fact doesn't. can declare new local var foo in function scope without collisions, if don't free foo variable resolve immutable binding. outweigh global foo variables higher in scope chain, however.
var foo = 1; (function foo() { "use strict"; var foo = 2; console.log(foo); // 2 }()); (function foo() { "use strict"; console.log(foo); // function … foo = 2; // error: invalid assignment in strict mode }()); are binding records stored in same lexical environment?
no. every named function expression enclosed in lexical environment has single, immutable binding function's name initialised function.
this described in function definition (§13) section of spec. while steps function declarations , anonymous function expressions "create new function object function body using current execution context's lexical environment scope", named function expressions more complicated:
- let
funcenvresult of callingnewdeclarativeenvironmentpassing running execution context’s lexical environment argument - let
envrecfuncenv’s environment record. - call
createimmutablebinding(n)concrete method ofenvrecpassingidentifierof function argument. - let
closureresult of creating new function object […]. pass infuncenvscope. - call
initializeimmutablebinding(n,v)concrete method ofenvrecpassingidentifierof function ,closurearguments. - return
closure.
it construct wrapper environment function expression. in es6 code block scopes:
var x = function foo(){}; // equivalent var x; { const foo = function() {}; x = foo; } // foo not in scope here what's behind phenomenon function name
fooaccessible inside invisible outside?
the foo immutable binding not created in current execution context's lexical environment, in wrapper environment used closure around function expression.
Comments
Post a Comment