🖲️

ミニマムで理解するプログラミング基礎 #JavaScript

に公開

プログラミング初級者に対して、簡単に説明する
初学者ではなく、何かしらの初心者向け教材を通った人向け

変数

値に名前を付けて使いまわせるようにする領域のこと

  • 宣言: 変数を使えるように定義すること
  • 命名: 変数に名前を付けること
  • 代入: 変数に値を入れること
// OK: 中身が使いまわせて、変数の値に何が入っているかがわかりやすい
// 変数`birthDay` を宣言し、"2022/03/22" を変数`birthDay`に代入する
const birthDay = "2022/03/22";
console.log(birthDay); 

// NG: 使いまわせない
console.log("2022/03/22");
console.log("2022/03/22");

// NG: aの中身がわかりにくい
const a = "2022/03/22";
console.log(a);

宣言のキーワード

JavaScript には、 const , let , var の3通りの宣言方法がある
※キーワード無し?知らんなぁ

再代入 再宣言 スコープ 推奨
const できない できない ブロック
let できる できない ブロック
var できる できる 関数 ×

推奨の理由は下記の通り。
できることが少ない=読み手が配慮することが減る

  • const は、再代入の必要がない場合に最も推奨。
    • 変更されない値であることが明確になり、コードの安全性が上がるため。
  • let は、後で値が変更される可能性がある場合に推奨。
    • ブロックスコープを持つため、var よりも予期せぬ挙動が少ないため
  • var は、現代のJavaScript開発ではほとんど推奨しない。
    • constlet に比べて、スコープの挙動が複雑でバグの原因になりやすいため。

変数の型

最低でも覚えておきたい3つだけ

型名 説明 分類
Boolean true または false false プリミティブ
Number 整数、浮動小数 42
3.1415
プリミティブ
String 文字列 "sa" プリミティブ

JSには上記以外を含めて計8種類(プリミティブ7つ + Object)のデータ型が定義されてる
null,undefined,Objectなど

https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Data_structures#プリミティブ値

なぜ型の理解が必要?

なぜ型の理解が必要なのか
変数resultには何が代入される?

question
const getTen = () => {
    return "10";
};

const addFive = (num) => {
    // num + 5の和を返す
    return num + 5;
};

const num1 = getTen();
const result=addFive(num1);
答え
  1. getTen()を実行する
  2. num1に"10"が代入される
  3. addFiveにはnum1="10"がわたる
  4. addFive()で、"10"+5を実行する
  5. この**+演算子は文字列の連結としてJSが解釈し**、"105"が実行結果となる
解説
const getTen = () => {
    return "10";
};
const addFive = ("10") => {
    // num + 5の和を返す
    return "10" + 5;
};
const num1 = "10"
const result=addFive("10");

配列

配列は複数の値をまとめる変数のこと。Array。List。

  • 長さ: 配列に入ってる値の個数のこと。length。
  • インデックス: 配列に入っている値が何番目かを表す。0から数え始める。添え字。
array
const names = ["taro", "hanako"];
console.log(names[1]);// hanako
console.log(names.length);// 2

配列のメリット

  • 今まで値ごとに1つ1つ宣言していた変数をまとめられる
  • まとまりのある値群が視認しやすい
  • 繰り返し処理で扱いやすくなる
曜日管理
// 配列ありの世界
// -------------------------------
const daysOfWeek = ["日","月","火","水","木","金","土"];

// 配列なしの世界
// -------------------------------
const sunday    = "日";
const monday    = "月";
const tuesday   = "火";
const wednesday = "水";
const thursday  = "木";
const friday    = "金";
const saturday  = "土";

オブジェクト

オブジェクトは、役割の異なる複数の値をまとめる変数のこと。

  • 他言語での KeyValue, HashTable, 辞書などと同等の扱い
  • プロパティ: オブジェクトを構成するキーと値のペアのこと
    • キー: プロパティの左辺。userId, name, birthdayなど
    • 値: プロパティの右辺。"slopwell", "すろっぺる", 11など
オブジェクト
const userInfo = {
    userId: "slopwell",
    name: "すろっぺる",
    birthday: "3月22日",
    age: 11
};
// どちらも同じ結果
console.log(userInfo.age);
console.log(userInfo["age"]);

image

userinfoを当てはめる
user-info

配列とオブジェクトの違い

配列 オブジェクト
用途 複数の値をまとめて管理する 複数のデータをまとめて管理する
オブジェクトは中身の値にプロパティと呼ばれる名前をつける
書き方 要素を [] で囲む
["apple", "banana", "orange"]
要素を {} で囲む
{name: "apple", price: 200}
コンソールへの出力 console.log(変数名) console.log(変数名)
要素の取り出し方 変数名[インデックス] 変数名.プロパティ名
変数名["プロパティ名"]

関数

関数とは、一連の処理をひとつにまとめる機能

  • メソッド、プロシージャ、サブルーチンなどと類語 (正確な違いは調べてください)
  • 関数を宣言する: 一連の処理をひとつにまとめて、定義すること
  • 関数を実行する: まとめた処理を呼び出して処理させること。 JSでは、 () を付ける。
関数
// 関数の宣言
const sayHello = () => {
    console.log("Hello");
    return "Hello"
};
// 実行OK
const result = sayHello();

// 実行NG () が付いていない
const result = sayHello;

引数と戻り値

  • 引数: 関数に渡す値

    • 仮引数: 関数に定義する変数
    • 実引数: 関数に実際にわたるデータ
  • 戻り値: 関数の呼び出し元に代入される値。return。

  • 引数・戻り値は必要に応じて定義すればOK。必須なわけではない。

引数と戻り値
// 引数と戻り値なし
// -----------------------
const sayHello = () => {
    console.log("Hello");
};
sayHello();

// 引数あり、戻り値なし
// -----------------------
const say = (msg) => {
    console.log(msg);
};
say("Hungry...");

// 引数あり、戻り値あり
// -----------------------
const sayThenMsgIsntEmpty = (msg) => {
    if (msg == null || msg == "") {
        return false;
    }
    console.log(msg);
    return true;
};
const result = sayThenMsgIsntEmpty("Hi!");
console.log(result);

関数を定義したほうがいい場合とは?

関数の作成は必須ではない。あくまでコードを整理するために用いる。
例えば以下の場合は、関数の定義を検討したほうがいいかも。

  • 複数個所で同じ処理があるとき (DRY観点)
  • スコープが肥大化しすぎたとき (単一責務観点)
  • 何の処理をしているかわかりにくいとき (可読性観点)

関数のメリット1 処理が何を目的としているかを理解するための情報が増える

関数のメリット1
// 関数のない世界
// ----------------------
const otya = 150 + 150 * 0.05;
const okashi = 10 + 10 * 0.05;
const manga = 484 + 484 * 0.05;
// なんとなく何の計算をしているかはわかるが、明示的ではない

// 関数のある世界
// ----------------------
// 税込み価格 = 本体価格 + 本体価格 x 税率
const calcPriceIncludingTax =(price) => {
    let taxRate = 0.05;
    return price + (price * taxRate);
};
const otya = calcPriceIncludingTax(150);
const okashi = calcPriceIncludingTax(10);
const manga = calcPriceIncludingTax(484);
// 関数にすることで「何を算出しているか」が明確になった

関数のメリット2 修正箇所が減る

関数のメリット2 もし税率が変わったら?
// 関数のない世界
// ----------------------
// 算式を1つずつ全部修正しないといけない…
// 間違えてしまう可能性も…
const otya = 150 + 150 * 0.05;
const okashi = 10 + 10 * 0.05;
const manga = 484 + 484 * 0.05;
// ↓
const otya = 150 + (150 * 0.08);
const okashi = 10 + ( 18 * 0.05);
const manga = 484 + (484 * 0.07);

// 関数のある世界
// ----------------------
const calcPriceIncludingTax =(price) => {
    let taxRate = 0.08; // ここを変更すればOK
    return price + (price * taxRate);
};
const otya = calcPriceIncludingTax(150);
const okashi = calcPriceIncludingTax(10);
const manga = calcPriceIncludingTax(484);

条件分岐

条件分岐とは、ある条件が成り立つかどうかで動作を変える処理のこと

コードにすると

分岐
const isWeekDay = true;
if (isWeekDay === true) {
    console.log("仕事をする");
}
  • 条件式: if() の括弧内の式のこと。
    • isWeekDay === true の部分
    • もし条件式がTrue※なら、ブロック内の処理を実行する
    • boolean型で表現する
    • ※(正確にはTruthly)
  • ブロック: { から } までのあいだの処理のこと

else句

elseは、条件に該当しなかったその他を処理するときに使用する。

コードにすると

else
const isWeekDay = true;
if (isWeekDay === true) {
    console.log("仕事をする");
} else {
    console.log("二度寝する");
}

if-elseif-else

複雑な条件分岐の例: OSから会社名を特定する。

  • Windows⇒Microsoft
  • macOS⇒Apple
  • 上記以外⇒わからない
if-elseif-else
const getCompanyByOS =(targetName)=>{
    if ("Windows" === targetName) {
        console.log("Microsoft");
    } else if ("macOS" == targetName) {
        console.log("Apple");
    } else {
        console.log("わかりません...");
    }
};
const osName = "Windows";
getCompanyByOS(osName);

switch文でも書ける

  • 式に対して、値がマッチしたcase節の処理を実行する。
  • マッチしなければdefault節を実行する。(default = else のイメージ)
switch
let getCompanyByOS = (targetName) => {
    switch (targetName) {
        case "Windows":
            console.log("Microsoft");
            break;
        case "macOS":
            console.log("apple");
            break;
        default:
            console.log("わかりません");
            break;
    }
};
const osName = "Windows";
getCompanyByOS(osName);

if文とswitch文の使い分け(主観)

switch文ではなく、if文にしたほうがいい場合

  • switch文内でネストが必要
  • case節からcase節が多い
NGパターン
// 変数msgのスコープがわかりにくい…
// 行数が増えるほど、どこからどこまでが1つのcaseなのかが視認しにくくなる…
// ※caseにブロックを付けて括るのも一つの解決策

const fortuneNum = 1;
const age = 5;
switch (fortuneNum) {
  case 0:
    const msg = "";
    if (age < 7) { // 幼児にUnluckyはかわいそう。。。
      msg = "Good luck!";
      console.log(msg);
    } else {
      msg = "Unlucky";
      console.log(msg);
    }
    break;
  case 1:
    console.log("Lucky!");
    break;
}

繰り返し

繰り返しとは、条件を設定して、同じ処理を何度も実行する処理のこと

  • 初期化式: let i = 0; の部分。ループ実行前の初回処理。
  • 条件式: i < 10; の部分。ループが回るための条件。これを満たしたときにループを抜ける。
  • 増分式: i++ の部分。ブロックの処理後に実行される処理。
ループ処理
for (let i = 0; i < 10; i++) {
    console.log(`ループ : ${i}回目!`);
}

// 繰り返しがなかったら…
console.log(`ループ : 0回目!`);
console.log(`ループ : 1回目!`);
console.log(`ループ : 2回目!`);
// ...
console.log(`ループ : 9回目!`);

for-of

for-of文は、配列向けのfor文。全要素に実行できる。

  • continue
    • 現在のループにおいて、後続処理が不要な場合にスキップする処理
    • 以降の処理を実行せずに増分式を実行する
    • ※for-of専用というわけではない
  • break
    • ループを中断する
    • 特定の処理が実行できて残りの処理が不要な場合に中断する処理。
    • 配列内に特定の要素が存在するかの確認などで利用する
for-of
// continue サンプル
const names = ["taro", null, "jiro"];
for (let name of names) {
    if (name === null) {
        continue;// 一致した要素はスキップ
    }
    console.log(name + "です!");
}

// break サンプル
const months = [1, 11, 12, 15];
let flag = false;
for (let month of months) {
    if (month === 11) {
        flag = true;
        break;
    }
}
if (flag === true) {
    console.log("みっけ!");
}

Discussion