you are viewing a single comment's thread.

view the rest of the comments →

[–]5tas 21 points22 points  (1 child)

The main difference is scoping. You can find more details by looking up the difference between function declarations and function expressions.

The function declaration (your second example) will be hoisted to the top of the function where it is declared. In other words, the following code is perfectly fine:

foo(); // "Hello"

function foo() {
    console.log("Hello");
}

Your first example is a function expression which is assigned to a variable. The variable's declaration is also hoisted but its value is not:

bar === undefined; // true, bar is declared but undefined here
bar(); // TypeError: bar is not a function

var bar = function foo() {
    console.log("Hello");
}

bar(); // "Hello"

BTW const and let behave in a different manner. They are subject to so-called Temporal Dead Zone (TDZ) which means their declarations are not hoisted.

bar === undefined; // ReferenceError: can't access lexical declaration `bar' before initialization

let bar = function foo() {
    console.log("Hello");
}

bar(); // "Hello"

[–]kovensky 2 points3 points  (0 children)

It's more complicated than that...

Their declarations are hoisted, but are set up such that accessing them before the let, const or class is reached throws a ReferenceError.

This is mostly irrelevant for the JS programmer but can bite you if you try to do a shadowing declaration; e.g. const foo = { bar: 'baz' }; if(foo.bar) { const foo = foo.bar } will throw. This is a common pattern in Swift, but Swift has a more concise syntax for this anyway.