変数のスコープ範囲

var animal = 'dog';

function ff(){
 alert(animal);
}

ff();

の実行結果は「dog」がalertされる。
関数内からグローバル変数は参照できる。

var animal = 'dog';

function ff(){
 alert(animal);
 var animal2 = 'cat';
 alert(animal2);
}

ff();

の実行結果は「dog」がalertされ、続けて「cat」がalertされる。
関数内で定義した変数は当然関数内から参照できる。

var animal = 'dog';

function ff(){
 alert(animal);
 alert(animal2);
}

function ff2(){
 var animal2 = 'cat';
}

ff();

の実行結果は「dog」がalertされたあと、「animal2 is not defined」とエラーになる。
関数から別関数内で定義した変数は参照できない。

var animal = 'dog';

function ff(){
 alert(animal);
 animal = 'cat';
 alert(animal);
}

ff();

の実行結果は「dog」がalertされ、続けて「cat」がalertされる。
グローバル変数は関数内で書き換えることが出来る。

var animal = 'dog';

function ff(){
 alert(animal);
 var animal = 'cat';
 alert(animal);
}

ff();

の実行結果は「undefined」がalertされ、続けて「cat」がalertされる。
なぜだ…?
と思い、以下のコードを実行。

var animal = 'dog';

function ff(){
 alert(animal);
 var animal;
}

ff();

の実行結果は「undefined」がalertされる。
というコトで自分なりの解釈だが、関数内でグローバル変数と同名の変数が定義された場合、
関数内では関数内の変数が有効になる(これはJavaと一緒)。
で、JavaScriptの実行は前の行から実行されるので、最後のサンプルだと(おそらく)変数はメモリ内に変数名「animal」で確保されているが、alert文の時点では変数が初期化されていないので、undifinedがalertされるのだろう(と推測)。
と思って、

var animal = 'dog';

function ff(){
 alert(animal2);
 var animal2 = 'cat';
}

ff();

の実行結果は「undefined」がalertされる。やっぱりそうだ。このコードで「animal2 is not defined」でなくundefinedがalertされるということは、変数は存在しているが初期化されていないということだ。