Created
November 29, 2016 21:28
-
-
Save bakkot/60121065ef615c26f8bdf42839e310df to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} |
I should mention that this is just a compatibility hack in the specification, since block-scoped function declarations were not previously a part of the ECMAScript spec but were commonly supported with inconsistent semantics in browsers. These semantics are only intended to capture behavior which would have worked across browsers, to avoid breaking things which previously worked everywhere; it's not intended to be sensible.
Don't write sloppy-mode code and you won't need to worry about it.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@kstratis, the spec has the full details.
The summary is:
In sloppy mode, block-scoped function declarations (usually) create two bindings: one scoped to the block, and one scoped to the function or script containing it. That is,
function f(){}
in a block is also secretlyvar f
. The function is hosted to the top of the block, like usual, but then when the declaration is executed it has the effect of reading from the block-scoped binding and copying its value to the var-scoped binding.In other words, the code above is a lot like the below, except that
f2
below is also namedf
.