2

I tried to implement a function using a switch, because I wanted to implement it differently, depending on the case. In a simple form, this is what it looks like:

function test() { console.log('hello world'); };
someVar = 'foo';
switch (someVar) {
  case 'foo':
    console.info('foo');
    function test() { console.log('foo'); };
    break;
  case 'bar':
    console.info('bar');
    function test() { console.log('bar'); };
    break;
  default:
    console.info('default');
    function test() { console.log('default'); };
}

test();

Now, the console says 'foo', but if you have a look at the source code of test, it will be function test() { console.log('default'); }. This is not a scoping issue though, since a switch does not have its own scope, plus the function's first declaration is before the switch.

However, if test is declared as a var and initialized in the cases, the result will be as desired.

But why is always the last function declaration implemented, independent from which case is actually executed?

Stacky
  • 875
  • 9
  • 24
  • 1
    Possible duplicate of [Javascript function scoping and hoisting](http://stackoverflow.com/questions/7506844/javascript-function-scoping-and-hoisting) – Rajesh Feb 24 '17 at 08:53

2 Answers2

4

Basically all named functions are hoisted and the last one overwrites the first with the same name.

The result is something like

function test() { console.log('hello world'); };
    function test() { console.log('foo'); };
    function test() { console.log('bar'); };
    function test() { console.log('default'); }; // this is the last one and in use

    someVar = 'foo';
    switch (someVar) {
        case 'foo':
            console.info('foo');
        break;
        case 'bar':
            console.info('bar');
            break;
        default:
            console.info('default');
    }
}

For function, which changes on switch, you could use an assignment to a variable of a function expression, you need.

function test() { console.log('hello world'); };
    var test;

    someVar = 'foo';
    switch (someVar) {
        case 'foo':
            test = function () { console.log('foo'); };
            console.info('foo');
        break;
        case 'bar':
            test = function () { console.log('bar'); };
            console.info('bar');
            break;
        default:
            test = function () { console.log('default'); };
            console.info('default');
    }
}
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
1

function x() {} declarations are hoisted; they're evaluated before the actual code is run. What you need to make this work is a function expression assigned to a variable:

var test = function () { ... };

switch (...) {
    case ...:
        test = function () { ... };
        break;
    ...
}

This will behave as expected, since it evaluates and explicitly reassigns the name test at runtime.

deceze
  • 510,633
  • 85
  • 743
  • 889
  • The dupe doesn't really explain "multiple hoisting", so may not fully answer the question. – deceze Feb 24 '17 at 08:59
  • Agreed. Then should we not post well explained answer over there as that post will be indexed higher and since its old post, it will have more discussion eventually giving more information? – Rajesh Feb 24 '17 at 09:01
  • Far be it from me to discourage de-duplication, but we don't have to merge everything with everything… :) – deceze Feb 24 '17 at 09:04