関数はJavaScriptの第一級オブジェクトです。この事は、その他の値と同じように渡す事が出来るという事です。この機能で良く使われる一つとして匿名関数を他のオジェクトにコールバックとして渡すというものがあり、これで非同期での実装が可能になります。
function foo() {}
上記の関数はプログラムの開始時の前に評価されるように巻き上げられます。従って定義されたスコープ内のどこでも使用する事が可能になります。ソース内での実際の定義が呼ばれる前でもです。
foo(); // このコードが動作する前にfooが作られているので、ちゃんと動作する
function foo() {}
var foo = function() {};
この例では、fooという変数に無名で匿名の関数が割り当てられています。
foo; // 'undefined'
foo(); // これはTypeErrorが起こる
var foo = function() {};
varは宣言である為に、変数名fooがコードが開始される実際の評価時より前のタイミングにまで巻き上げられています。fooは既にスクリプトが評価される時には定義されているのです。
しかし、コードの実行時にのみこの割り当てがされるため、fooという変数は対応するコードが実行される前にデフォルト値であるundefinedが代入されるのです。
他に特殊なケースとして、命名関数があります。
var foo = function bar() {
bar(); // 動作する
}
bar(); // ReferenceError
この場合のbarはfooに対して関数を割り当てるだけなので、外部スコープでは使用できません。しかし、barは内部では使用できます。これはJavaScriptでは名前解決による動作です。関数名はいつも関数自体のローカルスコープ内で有効になっています。