🌲

JavaScript 条件分岐と繰り返し処理

に公開

はじめに

今日もメモをとりながら講座を進めました〜
Railsで、あの時のあの構文はこういうことだったのか!という発見がたくさんあって、
頭に入ってきやすかったです🔰

条件分岐

IF文

let ok = false;
let maybeOK = false;

if (ok) {
  console.log('OK!');
} else if (maybeOK) {
  console.log('maybe OK...');
} else {
  console.log('NO!');
}

  • else ifを使うことで何個も分岐点を作ることができる!
  • if文はネストも可能だが見にくくなるので基本else ifを使う

「===」 と 「==」

「===」 同値演算子

ok = 1 === 1;

trueを返す!

  • 値が同じであればtrueを返す!

「==」 等値演算子

ok = 1 == 1;

trueを返す!

  • 値が同じであればtrueを返す!

二つの違いは、
「==」 の方が、型の制約がゆるい!

ok = 1 == '1';

true!

ok = 1 === '1';

false!

厳しくあればあるほど、予期せぬエラーを防ぐことができる!
ので、基本「===」を使う!

「!」

  • 値が同じで違えばtrueを返す!
ok = 1 !== 2;

オブジェクトと「===」を使う時は注意!

const coffee1 = { name: 'Cafe Latte' };
const coffee2 = { name: 'Cafe Latte' };

ok = coffee1 === coffee2;

中身は一緒でも、オブジェクトは違う!

ok = coffee1.name === coffee2.name;

名前だけ比べるならtrueが返る。

ここは、内部的な事情がわかってないといけないので、
ひとまずこんなことがあると覚えておく!

TruthyとFalsy

trueとして扱われる値とそうでない値がある。

これ以外は全てTrueになる!

論理演算子

AかつB、AまたはBみたいな。

  • 「&&」 論理積演算子や&演算子と呼ばれる。

AかつBの方!

ok = true && false;

この例だと、両方がtrueだった場合のみtrueになる。

厳密に言うと、、論理積演算子というのは、、
左側がtrueだったら、右側の値を返す。
左側の値がfalseだったら、左側の値を返すというのが定義。

ok = 'hello' && 'hi';

なので、これだとhiが、返ってくる!!

  • 「||」 論理和演算子やor演算子と呼ばれる。

AまたはBの方!

ok = true || true;

この例だと、両方がfalseだった場合のみfalseになる。

論理和演算子の方を厳密に言うと、
右側がどうであれ、左側がtruthyであれば左側を返すという感じ。
左側がfalseだった場合で、右側が合っていれば右側を返す。

応用的な使い方だと、、

const userInput = '';
const userName = userInput || 'User';
console.log(userName);

ユーザー名が空文字だった場合にデフォルトの値として、
userを入れる、などができる!

演算子の優先順位

ここに全て載っている!

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Operator_Precedence

NUll合体演算子

||でもやりましたが、
デフォルトの値として、userを入れる、などができるやつ!
ユーザー名が空文字の場合もとりたい!

const userInput = '';
const userName = userInput ?? 'User';
console.log(userName);

||ではなく、??で書いた場合は、
左の値がfalseじゃなくてnullかundefinedの場合は、
右の値を無視して左の値をとる!

しかし、「||」と「&&」と併用はできません!
文法エラーが出ます〜〜

ですが、どちらかが、()で囲われているなど、できる場合もあります!

論理否定演算子

  • 「!」 真偽値を反転させるもの!

よく使う方法として、、

const x = 15;
ok = !!x;
console.log(ok);

「!」というものは、右から左に計算するという結合性がある!
なので、右の!を計算した後に、左の!を計算するってこと!

15の反対は、false
falseの反対派trueとなって、反対の反対!

truthyであれば、true
falsyであれば、falseが返る感じになる!

つまり、型の変換、真偽値に肩を変換させてる!!

式と文

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference

ざっくり言うと、基本は全部文で
変数に代入できるものを特別に式と呼ぶ、ようなイメージ!
式文は、文の代わりとなった式のこと。
空分は、;だけ、何もしない文という意味になる文。

三項演算子

ブロック文を使って、複数の文を書く必要がない時は、
三項演算子を使うことで簡潔に書くことができる!

ok = 'hello';
ok = ok ? 'OK' : 'NO';

okがtruthyであれば、'OK'を返し、falsyであれば'NO'を返す!

switch文

if文とは違う条件分岐として使える文!

例えば、こういう関数があるとする。

function vegetableColor(vegetable) {
  if (vegetable === 'tomato') {
    console.log('tomato is red!');
  } else if (vegetable === 'pumpkin') {
    console.log('pumpkin is orange!');
  } else if (vegetable === 'onion') {
    console.log('onion is white!');
  }
}

vegetableColor('tomato');

これだと若干冗長。。
同じ書き方を3つしている🤔

switch文を使うと、こう書ける!

function vegetableColor(vegetable) {
  switch (vegetable) {
    case 'tomato':
      console.log('tomato is red!');
    case 'pumpkin':
      console.log('pumpkin is orange!');
    case 'onion':
    console.log('onion is white!');
  }
}
vegetableColor('tomato');

3つ出てくる🤔

なぜか?
上から順番に全部実行されているため!

(ちなみにcase文はswitch文の中でのみ使えます!)

これを防ぐために、、
break文を使う!

function vegetableColor(vegetable) {
  switch (vegetable) {
    case 'tomato':
      console.log('tomato is red!');
      break;
    case 'pumpkin':
      console.log('pumpkin is orange!');
      break;
    case 'onion':
      console.log('onion is white!');
      break;
    default:
      console.log('not found');
  }
}

break文を使うと、そこで終了してくれる!
なので、全ての場所でbreak文を使いましょう〜〜
(関数の中であれば、returnでも同じ意味になる!)

breakがないと下にどんどん進んでしまうという、特性を活かして
複数のケースに対して同じ処理を書くこともできる!

carrotとpumpkinのところ!

function vegetableColor(vegetable) {
  switch (vegetable) {
    case 'tomato':
      console.log('tomato is red!');
      break;
    case 'carrot':
    case 'pumpkin':
      console.log(`${vegetable} is orange!`);
      break;
    case 'onion':
      console.log('onion is white!');
      break;
  }
}
vegetableColor('carrot');

何も該当しなかった場合のdefaultの設定もできる!

    default:
      console.log('not found');

scopeについて

例えば、それぞれのcase文の中で、同じ定数を使いたい場合!

function vegetableColor(vegetable) {
  switch (vegetable) {
    case 'tomato':
      const message = 'tomato is red!';
      console.log(message);
      break;
    case 'pumpkin':
    case 'carrot':
      const message = `${vegetable} is orange!`;
      console.log(message);
      break;
    case 'onion':
      const message = 'onion is white!';
      console.log(message);
      break;
    default:
      console.log('not found');
  }
}

もう既にmessageは定義されていると言うエラーが出てしまう!

つまり、switch文の中ではscopeがあるが
それぞれのcaseの中では一切scopeがない!

なので、どうすれば良いか??

ここでブロック文を使う!
ブロック文と言うのは、ブロックスコープがあるので
その中で定義された変数や定数というのは他のところから参照できなくなる!

function vegetableColor(vegetable) {
  switch (vegetable) {
    case 'tomato': {
      const message = 'tomato is red!';
      console.log(message);
      break;
    }
    case 'pumpkin':
    case 'carrot': {
      const message = `${vegetable} is orange!`;
      console.log(message);
      break;
    }
    case 'onion': {
      const message = 'onion is white!';
      console.log(message);
      break;
    }
    default: {
      const message = 'not found';
      console.log(message);
    }
  }
}

こんな感じでブロック文で大きく囲うことで、
エラーが出なくなりました!

ループ文

while文
繰り返し処理

0~9まで表示させたい時!

let count = 0;
while (count < 10) {
  console.log(count);
  count += 1;
}

do while文

do {} while ();

do {}
まず、こちらの文が問答無用で何の条件もなしに実行される!

実行が終わったら、
while ()
このwhile文の右側の()にある条件式を評価!

それが、trueであればもう一度
do {}
この文が実行される!

= 繰り返されているということになります!

while文do while文の違いは、
一番最初に必ず実行される文があるかないかという違いになります!

例えば、、
countのところを100とした場合

(上がwhile、下がdo while)

let count = 100;
while (count < 10) {
  console.log('while: ', count);
  count += 1;
}

let tomatoCount = 100;
do {
  console.log('do-while: ', tomatoCount);
  tomatoCount += 1;
} while (tomatoCount < 10);

while文であれば、count 100<10でfalseなので、実行されずに終了するが
do while文の場合は、まず一度実行されるので、、

下記のような結果になる!

for文を使ってわかりやすくループする

構文
for (初期化式; 条件式; 更新式) {
  // 繰り返し実行するコード
}

1. 初期化式
ループの最初に一度だけ実行される式です。
通常、カウンター変数を初期化するために使用されます。

2. 条件式
各反復の前に評価される式です。
評価結果が真(true)の場合、ループは継続されます。
評価結果が偽(false)の場合、ループは終了します。

3. 更新式
各反復の最後に実行される式です。
通常、カウンター変数の更新や変更を行うために使用されます。

for (let pumpkinCount = 0; pumpkinCount < 10; pumpkinCount += 1) {
  console.log(pumpkinCount);
}

ちなみに、例文のpumpkinCountのscopeはfor文の外側からアクセスすることはできません!

カンマ演算子を使って、複数の式を一つにまとめる!

let文は、カンマを使ってもう一つ変数を定義することでできる!

let a = 'a', b = 'b', c;


(constでも可能です!)

そのため、for文でも同じように、カンマを付け加えられる!

そのletにつけたカンマとは別に、カンマ演算子というものもある!
複数の式を一つの式にまとめるような式!
(演算子の優先順位としては=よりも下、for文以外ではあまり使わない。)

pumpkinCount += 1, i += 1

この場合、左を実行して右を実行する感じになる。

for (
  let pumpkinCount = 0, i = 0;
  pumpkinCount < 10;
  pumpkinCount += 1, i += 1
) {
  console.log(pumpkinCount, i);
}

ちなみに、for文でiという変数はよく使われる!
i = iteration 反復する、繰り返すという意味!
が、分かりにくいのであまりおすすめはしない。

カンマ演算子を使うことでもっと複雑な式を取ることができました。

さいごに

今日はここまで〜〜
他にもやらなければいけないことが多いので、
休憩がてら進めていきます〜〜

Discussion