今回は、スコープについて解説していきます。
スコープとは
定義した変数は、どこからでも参照できるわけではありません。
以下のコードを書いて、コンソールで確認してみてください。
const myFunction = () => {
const x = 10;
const y = 5;
const result = x + y;
}
myFunction();
console.log(result);
コンソールには、「result is not defined」というエラーが表示されます。resultが定義されていないという内容のエラーです。
関数内で宣言された変数・定数は、関数外から参照することができません。
const myFunction = () => {
let num1 = 1;
var num2 = 2;
return num1 + num2;
}
myFunction();
console.log(num1);
console.log(num2);
letやvarも同様に、関数外から参照できません。
このように、変数・定数を参照できる範囲をスコープと言います。
次に、以下のように書き換えてください。
let result = 0;
const myFunction = () => {
const x = 10;
const y = 5;
result = x + y;
}
myFunction();
console.log(result);
resultは関数の外で宣言されているので、エラーが発生しません。
myFunction
を実行することでresultに15(10 + 5)が代入され、15がコンソールに出力されます。
このように、どこからでも参照できる変数(ここではresult)をグローバル変数と言います。
コードが長くなり処理が複雑になると、変数の値が意図せず書き換えられる恐れがあります。
できる限り変数は関数内で宣言し、グローバル変数を使わないようにした方が安全です。
const getSum = () => {
const x = 10;
const y = 5;
const result = x + y;
return result;
}
const printSum = () => {
const sum = getSum();
console.log(sum);
}
printSum();
全ての変数・定数を関数内で定義することでスクープを狭くし、意図しない書き換えや重複を防ぐことができます。
スコープは宣言によって異なる
次に、if文でのスコープを解説します。
script.jsを以下のように書き換えてください。
const x = 10;
if (x > 5) {
let msg = 'xは5よりも大きいです。';
}
console.log(msg);
コンソールを確認すると、このコードはエラーになります。
関数同様、if文も波括弧{}の中で宣言した変数は外から参照することができません。
次に、letではなくvarで変数を宣言してみます。
const x = 10;
if (x > 5) {
var msg = 'xは5よりも大きいです。';
}
console.log(msg);
コンソールを確認すると、「xは5よりも大きいです。」と表示されます。
同じ変数の宣言に使うletとvarですが、スコープの範囲が異なります。
ifやwhile、for文などで、{}
で囲まれた部分をブロックと呼びます。
letやconstはブロック内でしか参照できませんが(ブロックスコープ)、varは関数スコープのみで、ブロック内はスコープになりません。
letよりもvarの方が再代入されやすいため、letを使った方が意図せず変数が書き換えられる可能性が減ります。
まとめ
- 変数や定数は関数やブロック内で定義してスコープを狭くすることで、再代入や重複が起きないようにする。
- varはブロックの外で参照・再代入できてしまうので、letを使用する。