Skip to content

Instantly share code, notes, and snippets.

@sl4m
Last active May 5, 2016 14:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sl4m/7bb1ba7e15d564cdcfd7 to your computer and use it in GitHub Desktop.
Save sl4m/7bb1ba7e15d564cdcfd7 to your computer and use it in GitHub Desktop.
(function f() {
  function f() { return 1; }
  return f();
  function f() { return 2; }
})();

// multiple choice: 1, 2, Error (e.g. "Too much recursion"), undefined

JavaScript Quiz 12

There are several things going on here:

  • lexical scope - redefining a variable (f) within a scope
  • hoisting - specifically function declaration
  • a named, self-invoking function expression

The answer lies in this article by Ben Cherry called "JavaScript Scoping and Hoisting"

Lexical scope

f is redefined within the function f. Outside of the function, function f is untouched

x=1
function g () { echo $x ; x=2 ; }
function f () { local x=3 ; g ; }
f # does this print 1, or 3?
echo $x # does this print 1, or 2?

If lexical scoping, it will print out 1, 2. If dynamic scoping, it will print out 3, 1.

Name Resolution Order

  • Language-defined: All scopes are, by default, given the names this and arguments.
  • Formal parameters: Functions can have named formal parameters, which are scoped to the body of that function.
  • Function declarations: These are of the form function foo() {}.
  • Variable declarations: These take the form var foo;.

Function declaration has higher name resolution precedence than variable declaration.

Hoisting

Variable and function declarations are hoisted to the top of the scope.

var foo = 1;
function bar() {
  if (!foo) {
    var foo = 10;
  }
  alert(foo);
}
bar();

// will it alert 1 or 10?

What happens if

(function() {
  var x = 'foo'
  function x() { return 'bar'; }
  return x;
})();

// turns into

(function() {
  function x() { return 'bar'; }
  x = 'foo';
  return x;
})();

// x is 'foo'

In general, if a name has already been defined, it is never overridden by another property of the same name. This means that a function declaration takes priority over a variable declaration. This does not mean that an assignment to that name will not work, just that the declaration portion will be ignored.

Recommendations

  1. Declare variables at the top of scope.
  2. If using function declarations (vs. function expressions), be aware of its hoisting abilities.
  3. Do not use named function expressions (unless you're using it for profiling/debugging).

References

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment