Coverage and close priorities in javascript

It was introduced yesterday at TC39. You can find the gist here :

var p = () => console.log(f); { p(); // undefined console.log(f); // function f(){} f = 1; p(); // undefined console.log(f); // 1 function f(){} p(); // 1 console.log(f); // 1 f = 2; p(); // 1 console.log(f); // 2 } 

Can someone explain to me how this works? For recording, it works only in non-strict mode .

Thanks.

+5
source share
1 answer

I will not require an understanding of all the subtleties, but the main thing is the almost bizarre distortions of Appendix B ยงB.3.3.1 .

This code is effectively this, where f1 is the second copy of f characteristic of the lexical environment of the block (hence let below):

 var p = () => console.log(f); { let f1 = function f(){};; // Note hoisting p(); // undefined console.log(f1); // function f(){} f1 = 1; p(); // undefined console.log(f1); // 1 var f = f1; // !!! p(); // 1 console.log(f1); // 1 f1 = 2; p(); // 1 console.log(f1); // 2 } 

And, of course, thanks to the var , both p and f effectively declared at the top of the code snippet with the initial value undefined :

 var f = undefined; var p = undefined; p = () => console.log(f); { let f1 = function f(){};; // Note hoisting p(); // undefined console.log(f1); // function f(){} f1 = 1; p(); // undefined console.log(f1); // 1 f = f1; // !!! p(); // 1 console.log(f1); // 1 f1 = 2; p(); // 1 console.log(f1); // 2 } 

The key bit from B.3.3.1 is that it transfers the value of the internal f (which I called f1 above) to the external (below), F is the string "f" , the name of the function being declared):

3. When the FunctionDeclaration f function is evaluated, perform the following steps instead of the FunctionDeclaration evaluation algorithm described in 14.1.21:

a. Let fenv be the executable execution context of the VariableEnvironment.

b. Let fenvRec be a fenv EnvironmentRecord.

with. Let benv be the executable execution context of LexicalEnvironment.

e. Let benvRec be benv EnvironmentRecord.

e. Let fobj be! benvRec.GetBindingValue (F, false).

f. Do it! fenvRec.SetMutableBinding (F, fobj, false).

d. Return NormalCompletion (empty).

Recall that the variable environment is functional, but the lexical environment is more limited (to the block).

When it comes to trying to normalize function declarations in places where they were {invalid | unspecified} (choose your term), TC39 has a very treacherous path for navigation, trying to standardize behavior without breaking existing code that may have relied on implementation-specific behavior from the past (which were mutually exclusive, but TC39 is trying to achieve balance).

+2
source

Source: https://habr.com/ru/post/1260585/


All Articles