-2

Can someone explain the output of this code? I see one code test today and do not understand the output. I know it tests ES6 block scope. I'm fine with the first one, but not the others.

{
  function test() {}
  test = 123
}
console.log(test)
console.log(typeof test)

{
  function test1() {}
  test1 = 123

  function test1() {}
}
console.log(test1)
console.log(typeof test1)

{
  function test2() {}
  test2 = 123

  function test2() {}
  test2 = 345
}
console.log(test2)
console.log(typeof test2)

Can someone explain me why the output is:

ƒ test() {}
function
123
number
123
number
Moon
  • 128
  • 3
  • 14
  • 2
    Function declarations in block statements and implicit globals ... this really is not a practical programming question, both are a big no no. – Teemu Apr 17 '20 at 15:49
  • Yes, I absolutely agree it's not a good behavior. No one will do this I believe. I saw this on one interview question list... – Moon Apr 17 '20 at 16:32
  • Acturally, according to https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function, Conditionally created functions , not all browser make the function hoisted. – Moon Apr 18 '20 at 08:06

2 Answers2

1

"use strict" should help you to avoid such weird behavior.

vitkarpov
  • 399
  • 2
  • 8
  • After many researches for the block-level functions in non-strict code, I should say that ouput is not correct. I only tested in Chrome, however, after I check the MDN, on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function, Conditionally created functions, the result is not same. And to avoid this wired output, we can use strict mode, and a safe way is use function express as here say, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions, in Block-level functions in non-strict code. – Moon Apr 18 '20 at 08:04
1

I finally find the answers, I know nobody will write code totally same as I posted, using block directly, however, if you see this, javascript- Uncaught SyntaxError: Identifier * has already been declared, it's possible we may write code wrong if we don't have good understanding about scope in JS. I should mention the code should run in ES6 instead of ES5 strict mode, also mention it's running on Chrome which the browser supports the ES6, so sorry to confuse vikarpov.

Based on, http://www.ecma-international.org/ecma-262/6.0/#sec-additional-ecmascript-features-for-web-browsers, B.3.3, Block-Level Function Declarations Web Legacy Compatibility Semantics, In ES6, the function declaration in the block uses ES6 declaration semantics (like let or const), which does not allow redeclarations.

So the answer is

{
  function test() {}
  test = 123
}
console.log(test)
console.log(typeof test)

will be

var test
{
    let test = function test() {};
    window.test1 = test1
    test = 123;
}
console.log(test) //f test(){}
{
  function test1() {}
  test1 = 123

  function test1() {}
}
console.log(test1)
console.log(typeof test1)

will be

var test1
{
    let test1 = function test1() { }
    window.test1 = test1
    test1 = 123
    window.test1 = test1
}
console.log(test1) //123
{
  function test2() {}
  test2 = 123

  function test2() {}
  test2 = 345
}
console.log(test2)

will be

var test2
{
    let test2 = function test2() {}
    window.test2 = test2
    test2 = 123
    window.test2 = test2
    test2 = 345
}
console.log(test2)
Moon
  • 128
  • 3
  • 14