A diferença entre as declarações de função JavaScript

A maioria de vocês sabe que existem duas maneiras de declarar uma função em javascript:

function foo() {
console
.log('bar');
}

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

Eu nunca soube que há uma grande diferença entre esses dois que pode afetar sua arquitetura de código. Vejamos um exemplo com o primeiro método de declaração:

foo();
function foo() {
console
.log('bar');
}

Isso será gerado bar, mesmo que a função seja definida após a chamada inicial. Bem, esse é o comportamento esperado. Defina uma função em qualquer lugar e você poderá chamá-la de onde quiser. No entanto, fazer o mesmo com a segunda abordagem:

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

Irá resultar em uma agradável exceção: .Uncaught TypeError: undefined is not a function

Embora isso possa não ser uma grande notícia para a maioria de vocês, certamente foi uma surpresa bem-vinda para mim hoje!