対象者
- 関数や変数を習ったけど、 グローバル変数や スコープといったキーワードがなかなか理解できない
- 関数が入れ子になったとき、変数/関数の 宣言場所や 引数ってどんな挙動するの?
スコープ=範囲とは
プログラムで使用される変数は自由に名前を設定できますよね?
すると、同じ名前にしたり、上書きしたりと、プログラム側はブレない基準で処理しないといけないです。
そのため、 宣言場所によって、使用できる 範囲を制限します。
関数の外で宣言した変数は関数の中でも宣言せずに使用することができます。これを グローバル変数と呼びます。
let global_v = 0; // グローバル変数
function f1() {
// 変数宣言不要!
console.log(global_v); // 0が表示される
}
f1(); // ここで関数を実行します
ちなみにですが、以下のように関数内で同じ変数名で宣言してしまった場合、関数内の変数が優先されます。
非推奨!
バグの原因ですので、良くない書き方なのです。(バグ原因を探す一つとしてご紹介しています)
let global_v = 0; // グローバル変数
function f1() {
let global_v = 1;
console.log(global_v); // 1が表示される
}
f1(); // ここで関数を実行します
バグの嵐
引き続き非推奨の書き方を列挙していきます。
関数宣言時の引数名
以下の例では、関数f2()
の引数名にv1
というグローバル変数と同じ名前を書いているため混乱のもととなります。
上記と同様に引数は関数内のみで有効のローカル変数として定義されるので、return
などしないと関数の外では使えません。
let v1 = 0;
function f1() {
v1 += 1;
console.log("in1-" + v1); // in1-1
}
function f2(v1) { // 下の関数呼び出しの箇所で引数にグローバル変数のv1を指定しています
v1 += 1; // 引数として呼び出したローカル変数の処理。
console.log("in2-" + v1); // in2-2
// このローカル変数のv1は特にreturnしていない
}
f1();
console.log("out1-" + v1); // out1-1
f2(v1); // 引数にグローバル変数のv1を指定しています
console.log("out2-" + v1); // out2-1 特にreturnされていないのでf1()で計算されたグローバル変数のv1を表示します
関数内に関数を宣言したとき
変数だけでなく、関数にもスコープがあります。
そのため、 どこで宣言したかが重要になったりします!
function main(){
console.log("hoge");
function child(){ // main関数内での関数宣言
console.log("huge");
}
child(); // main関数内ではスコープ内なので実行できる
}
main();
child(); // こちらはスコープ外なので実行できない
今日(2022/5/19)のところはひとまずここまで。
気が向いたら追記しまふ。