[javascript] Q. 変数のスコープとは?

A.
変数を参照できる範囲を"スコープ"と呼びます。

JavaScriptのスコープは大きく分けて2つのスコープがあります。
グローバルスコープ
ローカルスコープ

グローバルスコープに属する変数はプログラムのどの部分からも参照が可能です。
JavaScriptでは関数の外側宣言した変数はグローバルのスコープになります。
関数外で宣言された変数をグローバル変数と呼びます。

ローカルスコープに属する変数は、ローカルスコープの有効範囲内でのみ参照が可能です。
JavaScriptでは関数を作成するとその関数内がローカルのスコープになります。
関数内で宣言された変数をローカル変数と呼びます。

実際に変数のスコープを確認してみましょう。

グローバル変数とローカル変数をそれぞれ別の変数名で宣言
var a = 'global'; // グローバル変数

function testFunction() {
  var b = 'local'; // ローカル変数を作成
  console.log(a); // global
  console.log(b); // local
}

// 関数を実行
testFunction();

console.log(a);	// global
console.log(b);	// Can't find variable: b
関数内(ローカル)で宣言された変数は関数外(グローバル)では参照できない事が確認できます。

グローバル変数とローカル変数をそれぞれ同じの変数名で宣言
var a = 'global'; // グローバル変数

function testFunction() {
  var a = 'local'; // ローカル変数を作成
  console.log(a); // local
}

// 関数を実行
testFunction();

console.log(a);	// global
スコープが異なるので、同じ変数名が使われても別の変数として扱われます。

グローバル変数とローカル変数をそれぞれ同じの変数名だがvar命令なしで宣言
var a = 'global'; // グローバル変数

function testFunction() {
  a = 'local'; // var命令を使わない
  console.log(a); // local
}

// 関数を実行
testFunction();

console.log(a);	// local が表示される
変数名にvar 宣言をつけない場合グローバル変数として扱われるので
関数内でも同じ変数として認識されるので注意が必要です。

またJavaScriptにはブロックにおけるスコープは無いので他の言語で
この概念に慣れている人は注意が必要になります。
var a = 'hoge';
if (true) {
  var a = 'test';
}
console.log(a); // test

関数の仮引数のスコープについて
仮引数とは関数が呼び出される時に渡される値を一時的に保存する変数です。
関数の仮引数は、ローカル変数として処理されます。
var x = 10;
function calc(x){
  x = x * 10;
  return x;
}
console.log(calc(10)); // 100
console.log(x); // 10
関数の内部でxの値が100になります。
しかしながら関数の外ではxはグローバル関数なので
変更の影響を受けず10のままです。

仮引数に基本型の値をを渡した場合については、
仮引数の内容を変更してもグローバル変数で定義した値に影響を
及ぼさない事は確認できました。

参照型で渡される場合についても確認してみましょう。
var ref = ['apple', 'orange', 'remon'];
function test(ref) {
  console.log( ref.toString() ); // apple,orange,remon
  ref.shift();
  return ref;
}
console.log(test(ref).toString()); // orange,remon
console.log(ref.toString());  // orange,remon
参照型の変数が渡されると仮引数には参照値が渡されます。
仮引数で保存されているのは、渡された変数の参照なので
仮引数の操作を加えると、参照元の実際の値が操作されるので
呼び出し元の変数も影響は受けます。

関数の仮引数で、参照型の値を使い値を操作する時には
呼び出し元の変数の値にも影響するので注意して操作を行う必要があります。