5

var a; 
{
  function a() {}
  a = 60;
  console.log('1: ', a);
}
console.log('2: ', a);

var b; 
{
  b = 60;

  function b() {}
  console.log('3: ', b);
}
console.log('4: ', b);

The output is:

1: 60
2: f a() {}
3: 60
4: 60

I can't figure out why, if I remove the curly braces, it all prints 60. Perhaps because of hoisting. But a function declaration doesn't have lexical scope as far as I know, and even if it does, the first output should print the function, right?

Boann
  • 48,794
  • 16
  • 117
  • 146
Drake Xiang
  • 368
  • 1
  • 7
  • 14
  • 1
    Yes for the legacy code compatible we have block scoped function, [`Block scope function`](https://tc39.es/ecma262/#sec-block-level-function-declarations-web-legacy-compatibility-semantics), but i having hard time to read the docs to understand why the placement of variable makes difference, my guess as far as i understood, if depends on `functioninitialization` during execution context because of conflicting name, it created different kind of binding which depends on duplicate name, – Code Maniac Sep 29 '19 at 04:32
  • Here are some links i think can lead to answer who ever have knowledge or experience of reading ECMASCRIPT docs, 1) [`Function deceleration initialization`](https://tc39.es/ecma262/#sec-functiondeclarationinstantiation) 2) [`Global deceleration initialization`](https://tc39.es/ecma262/#sec-globaldeclarationinstantiation) 3) [`Create binding`](https://tc39.es/ecma262/#sec-declarative-environment-records-createmutablebinding-n-d) – Code Maniac Sep 29 '19 at 04:37
  • 2
    Always use strict mode! You'd get the proper output `60`, `undefined`, `60`, `undefined` with that :-) Have a look at [What are the precise semantics of block-level functions in ES6?](https://stackoverflow.com/q/31419897/1048572), although it doesn't explain what happens when there already is a conflicting (same-name) `var` declaration in the outer scope. – Bergi Sep 29 '19 at 15:40

0 Answers0