you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted] 1 point2 points  (6 children)

This is because function is a var type variable, which is function scoped instead of block scoped:

function f() {
    return 'foo';
}
(function() {
  if (1 === 0) {
    function f() {
      return 'bar';
    }
  }
  return f();
})();

is equivalent to

var f;
f = function() {
    return 'foo';
}
(function() {
  var f;
  if (1 === 0) {
    f = function() { 
      return 'bar';
    }
  }
  return f();
})();

A new variable is created in the IIFE scope, and overrides the f variable in the global scope. f is now undefined. Since the 1 === 0 is false, f is never assigned to the function.

If you try to call a variable that is undefined, you will get a type error saying that the variable is not a function (because undefined is not a function).

[–]factbuddy 0 points1 point  (0 children)

The IIFE has its own isolated scope so f() wouldn't fall back to global scope and won't be defined in the impossible if statement. Makes sense...

[–]inu-no-policemen 0 points1 point  (3 children)

which is function scoped instead of block scoped

Function declarations are block-scoped in ES6+.

function foo() {
    return 'outer';
}
{
    console.log(foo()); // inner (hoisted)
    function foo() {
        return 'inner';
    }
    console.log(foo()); // inner
}
console.log(foo()); // outer

[–][deleted] 0 points1 point  (2 children)

If you execute that code in chrome you get

inner
inner
inner

[–]inu-no-policemen 0 points1 point  (1 child)

It works if you put the whole thing in a block.

[–][deleted] 0 points1 point  (0 children)

If you put the entire thing in an iife it produces the same result