alienHRNの訓練日記

IT業界初心者で勉強中。

◆20200817 授業メモ スコープ・ドラクエの答え合わせ

本日の授業内容
〇スコープについて
変数の参照範囲のことを言う。
・グローバルスコープ
関数内・関数外で参照できる
・ローカルスコープ
関数内のみ参照できる
 
変数宣言の種類
1.無名
例)num1=100;
グローバル変数。バグやエラーの原因になるので非推奨
 
2.var
宣言場所によってグローバル・ローカルになりうる
同盟変数の宣言はOK
 
3.let
宣言場所によってグローバル・ローカルになりうる
同盟変数の宣言はNG
ブロックスコープを持つ(宣言したブロック({}内)のみ使用可能)
 
4.const
定数の宣言:値の再代入ができない
読み取り専用変数
 これも同盟変数の宣言はNG。
 変数名を全て大文字にするという暗黙のルールがある
 
〇ローカルスコープ・ブロックスコープを用いた演習問題
 
 
 
 
以下板書
 
 
 
〇スコープとは
変数の参照範囲のことをいう

14 global_scope1.jsより

例題
// 関数の定義
// 呼び出されたときに関数ブロック内を実行。
function test() {
  console.log('関数内:' + num);
  // グローバル変数は関数内からも参照可能
}

console.log('1回目の出力');
var num = 100;
// 関数外で宣言された変数は
// グローバルスコープを持つ
// グローバル変数として扱われる
console.log('関数外:' + num);
test();//引数なし戻り値なし関数の呼出し


// 変数宣言の種類(全4種)

// 宣言用のキーワードなし
num1 = 100;

// var
// 宣言場所によってグローバル変数・ローカル変数にもなり得る

var num2 = 200;
var num2 = 2000//← 同盟変数の宣言おk。但しバグの温床になりがち
// うっかり違う値を管理する同盟変数を上書きしてしまうリスク。


// let
// 宣言場所によってグローバル変数・ローカル変数にもなり得る
// 同盟変数の宣言はNG。
// ブロックスコープを持つ
// 迷ったらletを使うとバグのリスクを減らせるかも。
let num3 = 300;


// const
// 定数の宣言:値の再代入ができない
// 読み取り専用変数
// これも同盟変数の宣言はNG。
// 変数名を全て大文字にする(推奨)
const num4 = 400;
// num4 = 4000; //←代入エラー



〇ローカルスコープローカル変数
宣言したブロック大カッコ{ } )内でのみ利用可能


function test() {
  var num = 100;//←{}内のみ使える変数
  //ローカルスコープを持つローカル変数
  //関数内でのみ使用可能
  console.log('関数内:' + num);
}

console.log('1回目の出力');
test();//関数呼び出し
console.log('関数外:' + num);//←よってこの場合エラーになる。



例題
14 function_scope2.jsより

function recoveryMagic(playerIDmagicID) {
  // var magicList = [
  //   { name: 'ホイム', point: 100 },
  //   { name: 'ベホイム', point: 200 },
  //   { name: 'ベホムズン', point: 300 },
  //   { name: 'メル', point: -20 },
  //   { name: 'メラム', point: -100 },
  //   { name: 'メルゾーマ', point: -300 },
  // ];←ここに変数を宣言するとエラーになる。

  console.log(playerList[playerID].name + 'は'
    + magicList[magicID].name + 'を唱えた!'
    + magicList[magicID].point + '回復');
  return magicList[magicID].point;
}


function attackMagic(playerIDenemyIDmagicID) {
  // 使用する魔法情報をそれぞれ宣言して代入
  // 魔法情報のIDが変わるので注意
  console.log(playerList[playerID].name + 'は'
    + magicList[magicID].name + 'を唱えた!'
    + enemyList[enemyID].name + 'へ'
    + -magicList[magicID].point + 'のダメージ!');
  return magicList[magicID].point;
}

var playerList = [
  { name: '田中'life: 1000 },
  { name: '佐藤'life: 500 },
];
var enemyList = [
  { name: 'スライム'life: 10 },
  { name: 'スライムキッド'life: 100 },
];


// 関数外で宣言されているのでグローバル変数
// 関数内から参照可能になる
var magicList = [
  { name: 'ホイム'point: 100 },
  { name: 'ベホイム'point: 200 },
  { name: 'ベホムズン'point: 300 },
  { name: 'メル'point: -20 },
  { name: 'メラム'point: -100 },
  { name: 'メルゾーマ'point: -300 },
];


console.log('1回目の出力');
playerList[0].life += recoveryMagic(01);
console.log(playerList[0].life);
enemyList[1].life += attackMagic(113);
console.log(enemyList[1].life);


〇各スコープに同名変数
14 w_scope1.jsより

function test() {
  var num = 200;//ローカル変数宣言
  console.log('関数内:' + num);
  // ローカル変数が優先される
  // 対象のローカル変数が存在しない場合、
  // グローバル変数を参照しに行く
}

console.log('1回目の出力');
var num = 100;
test();
console.log('関数外:' + num);



ブロックスコープ
14 block_scope.jsより

console.log('1回目の出力');
if (true) {
  var num1 = 100;
  // ブロック内で変数宣言
  // varで宣言した場合はブロックスコープなし
  console.log('ブロック内:' + num1);
}
console.log('ブロック外:' + num1);
// ブロックスコープなしなのでブロック外でも使用可能
// →よって{}外でも表示される

console.log('2回目の出力');
if (true) {
  let num2 = 200;
  // ブロック内で宣言
  // letはブロックスコープありなので
  // 宣言したブロック内({}内)のみで利用可能
  console.log('ブロック内:' + num2);
}
console.log('ブロック外:' + num2);
// →よって{}外なのでエラー表示になる

let num2 = 300
// スコープ内にnum2が宣言されてなければ
// letで同盟変数を宣言できる


for (let i = 0i < 5i++) {
  // for文の()内で宣言した変数は
  // forブロック内で宣言した変数と同じになる。
  console.log(i);
}


console.log(i);//←これはエラーになる。
// 変数iはブロックスコープを持っておるので
// for文外で使用することはできない。


console.log('検証3');
var time = 10;
if (time < 12) {

  var message = 'おはよー';
else if (time < 18) {
  var message = 'こんにちは';

else {

  var message = 'こんばんみ';

}
console.log(message);

letで基本的に記述すること
そうすることでエラーやバグの回避につながる


console.log('検証4');
console.log(num98)
let num98 = 100;

// letで宣言された変数は巻き上げ対象から外れる


〇const
14 Constant.jsより

console.log('1回目の出力');
const NUM = 100;
console.log(NUM);
NUM = 200;//エラーになる
// 定数の値の再代入は不可
console.log(NUM);
// constで宣言すると定数
// 初回のみ代入可能で2回目以降は代入不可
// 暗黙のルール:変数名は全て大文字
// 値の変更がない場合は全て定数が望ましい


〇未宣言変数
14 undeclared.jsより

function test() {
  num = 100;
  // ↑キーワードなしの変数はグローバル変数
  console.log('関数内:' + num);
}

// 関数内で作成した未宣言変数はグローバル変数として扱う
// 故に関数外で利用することが可能

console.log('1回目の出力');
test();
console.log('関数外:' + num);
// バグやエラーの原因になりやすいのであまり使用はおすすめしない


for文で使われるiについて
for (i = 0i < 5i++);
カウント変数が未宣言変数
関数外でiが使えるようになってしまう