0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JavaScript基礎習得メモ

Last updated at Posted at 2025-07-20

こんにちは。
タイトル通り、本日から「JavaScript基礎習得メモ ~27歳・未経験からWeb系転職を目指して~」を書いていきます。

経緯としては、かれこれ2年ほど、現職と平行し Web制作会社への転職を目指して、あっちこっちスキルに手を付けたり、ポートフォリオサイトをいくつか制作しましたが、やってみたいという強い思いとは裏腹、一向に'コードを書くこと'への苦手意識が消えず...。

そろそろ焦らないとまずいと思い、'フロントエンド'の方向に進みたいという前提で、MENTAにてプロの方へアドバイスを募ったところ、
「JavaScriptは一生稼げる1番の友達」
「React→Next.jsは現場全員が使っている超必修スキル」
との名言をいただきまして。モチベーションアップにつながりました。

今後の学習方法としては、
・ドットインストールのJavaScript動画を片っ端から見直し、出来る限り詳細に、どこが分かる/分からないを整理する(分からなくてもとりあえずメモ)。
・ドットインストール公式様が出しているnote記事「JavaScriptに挫折しそうな方への提案 〜 自分で書けるようになるまで」(以下URL)を参考にする。
...といった要領で進めていこうと思います。
https://note.com/dotinstall/n/n9e2c2eedc096

はじめに。注意。

偶然この記事にたどり着いた方、ごめんなさい。本当に拙いです。初歩の初歩状態です。間違っているところもあるかもしれません。勉強しながら継続して編集していきます。

はじめてのJavaScript(全7回)

  • jQueryやBootstrapとは違い、自分の欲しい機能をとことんカスタマイズできるようになる。Node.js、Reactに展開可能
  • タブメニューや計算ツールなど、細部までコードには触れないが、出来ることがたくさんあることが分かる序章
  • 多少分からないことがあっても、先に進むべし

JavaScript入門 基礎文法編(全27回)

  • ライブラリやフレームワークへ進む前に、基本的な文法をしっかりと確認しておくこと
  • alert(メッセージ);console.log(メッセージ); →シンプル。不明点は特になし
  • 演算:console.log(10 ** 3); = 1000→べき乗。知らなかったので覚えておく
     
  • const→定数の宣言に使われる(消費税の計算など)。=で代入
  • あとで値を再代入したい場合はlet=「変数」で宣言する
  • 値が途中で変わっていたりするとコードが読みづらいため、基本的にはconstで宣言し、仕方ない時だけletにする。(varは古いので使わない)
  • 値を変えないものは const、値を変える必要があるなら let
     
  • ${...} 定数や変数を埋め込む(「テンプレートリテラル」という)
  • 「~と等しい」は===、「~と等しくない」は!==を使う('='の数に注意)
  • if (条件) {出力} else if (条件) {出力} else (条件) {出力} お馴染みの条件分岐
  • 右クリック→「ドキュメントのフォーマット」でインデントを綺麗に整理できる。(初耳でした。汗)
     
  • スコアなど数値でなく、値が定まっている文字列で条件分岐させる場合は、switchを使う。switch (...) {case '...': console.log('...'); break; default: console.log('...'); break;}
     
  • for:反復処理。条件を満たしてる段階まで処理を繰り返す。例:for (let price = 150; price <= 160; price++)
  • do...while:最低1回は必ず処理を実行し、その後whileの条件を評価してループ継続するか判断する構文。例:ユーザー入力によるメニュー選択など、「最初に一度は案内を出したい」時('1~3からメニューを選んでくださいなどの状況')に使う
let command;
do {
  command = Number(prompt('Menu 1, 2, 3 or 0 to exit'));
  // do=初期メッセージとして必ず1度は表示させる
  if (command === 0) {
    console.log('終了します');
    // 0を押すことで卓上メニュー端末の動作を終了
  } else {
    console.log(`メニュー${command}を処理中...`);
    // お客様が1~3の中で食べたいものを選択中
  }
} while (command !== 0);
// while:command が 0 でない限り、do の処理を繰り返す
// → 「0以外の数字(1~3)が入力されたらメニュー処理を継続」

// do...while文:最初の1回は必ず実行されるループ
// ユーザーにメニュー番号を入力させ、0が入力されるまで繰り返す
  • ifforwhiledo...whileの違い:
    • if:条件が「1回だけ」真かどうかを判断して、そのときだけ処理を実行する。→ 「ある条件のときに一度だけ処理したい」ときに使う
       例:if (score > 80) { console.log('よくできました'); }
       
    • for最初から「何回繰り返すか」が分かっているときに使う
       例:150〜160円の値段で繰り返す→for (let price = 150; price <= 160; price++) { console.log("Price: " + price); }
       
    • while:条件が「真の間、何度も繰り返し」処理を実行する。→ 「条件を満たす間、何度も処理を続けたい」ときに使う
       例:let count = 0;  while (count < 3) { console.log('処理中...'); count++;}
       
    • do...while:条件に関係なく、まず1回だけ実行し、その後で条件を判定して繰り返す。→ 「とにかく1回は処理を実行したい、その後も条件次第で繰り返したい」ときに使う
       例:ユーザーへ何度も入力を求めたいが、必ず最初に1回は聞く必要があるとき→let command; do { command = Number(prompt('Menu 1, 2, 3 or 0 to exit'));   console.log(メニュー${command}を処理中...); } while (command !== 0);
       
      ☆使い分け:よく使われるforを試してみて、うまくいかなかったらwhile、それでもうまくいかなかったらdo...whileという使い分けで書いてみる
       
  • break:反復処理全体から抜けるための命令
  • continue:反復処理の途中でそれ以降の処理をスキップして、次の反復処理に移るための命令
     
  • ifを使うまでもない短い条件の場合は、三項演算子?を使う
    例:score < 30 ? 'Team A' : 'Team B'は、score が30より小さいなら'Team A'、そうでなければ 'Team B'となり、scoreが40の場合、30未満ではない=false='Team B'が出力される。※複雑な条件や処理にはif / elseを使うこと
     
  • 論理演算子 &&:なおかつ ||:または
  • スコープ:定数や変数の参照可能な範囲 → JavaScriptでは主に「グローバルスコープ」「ローカルスコープ」の2つがある
'use strict';

let x = 10;

{
    let x = 20;
    console.log(x);
}
// {}内はローカルスコープと呼ばれる。出力は20。

console.log(x);
// {}外はグローバルスコープと呼ばれる。出力は10。

※別のjsファイルでxを使いたい際にローカルスコープを使用する。

  • 基礎文法編まとめ(感想)
    関数などが出てきていないため、'本番っぽいコード'ではないものの、大切な基礎が詰まっていた。forwhiledo...whileや、if / elseと三項演算子?の使い分けが難しく感じたが、こうした基礎が頭に入っていて、必要な時に思い出して使えるのが'書ける'という状態なのだなと感じた。

JavaScript入門 関数編(全12回)

  • 関数はreturnを使って結果を返す。returnを省略すると、返り値はundefinedになる。console.log()は「表示」するだけで、値を返していない。他の関数や処理で再利用したい場合は、必ずreturnで返すこと
function sum(a, b) {
  return a + b;
}

console.log(sum(3, 7) * 2);  // → 20
  • 引数のデフォルト値:関数に初期値を設定することで、引数が省略された場合にも安全に処理を行える。消費税率や送料など、オプション的な値を関数内で処理したいときに使う
'use strict';

{
  function calculateTotal(price, amount, rate = 1.1) {
    return price * amount * rate;
  }

  console.log(calculateTotal(100, 10));         // → 1100(rateは1.1)
  console.log(calculateTotal(150, 10));         // → 1650(rateは1.1)
  console.log(calculateTotal(200, 10));         // → 2200(rateは1.1)
  console.log(calculateTotal(120, 10, 1.08));   // → 1296(rateを上書き)
}
  • 早期リターン:条件に合えばすぐreturnして、それ以降の処理をスキップする書き方。ifreturnで無駄な処理を省いてコードをスッキリ書ける
'use strict';

{
  function calcurateTotal(price, amount, rate = 1.1) {
    // 早期リターン実装前
    // if (amount >= 100) {
    //   return price * amount;
    // } else {
    //   return price * amount * rate;
    // }

    if (amount >= 100) {
      // 早期リターン
      return price * amount;
    }
    return price * amount * rate;
  }

  console.log(calcurateTotal(100, 100));
  console.log(calcurateTotal(1000, 10));
  • 引数のスコープ:JavaScriptでは、関数の引数や中で定義した変数は、その関数の中(スコープ)でしか使えず、関数の外で同じ名前を使おうとすると、エラーになる
'use strict';

{ // ←この{}は「スコープブロック」と言って関数ではないので注意!=外!
  function double(num) {
    // ← 「中!」:この中だけで num は使える
    return num * 2;
  }

  function triple(num) {
    return num * 3; // ← ここも「中!」だから num は使える
  }

  console.log(double(10)); // → 20

  // ↓↓↓ 「外!」で num を使おうとするとエラー!
  // console.log(num); // エラー:num is not defined

  console.log(triple(20)); // → 60
}
  • 実践すべき技:同じ処理を関数にまとめることで、コードの重複を減らし、保守性も高くなる
'use strict';

{
  function showAd() {
    console.log("---------");
    console.log("SALE! 50% OFF!");
    console.log("---------");
  }

  function showContent() {
    console.log("BREAKING NEWS!");
    console.log("Two baby pandas born at our Zoo!");
  }

  showAd();        // 同じ広告表示を関数で共通化!
  showContent();
  showAd();
}
  • 関数宣言と関数式:JavaScriptでは、関数を「関数宣言」と「関数式」という2つの方法で定義できる
    まず 「関数宣言」 は、関数を先に呼び出しても動作する。これは「ホイスティング」という、コードのどこに宣言を書いても実行時には、コードの先頭へ書いたことになる仕組み(=関数の巻き上げ)があるため。
  • 一方 「関数式」 は、関数を変数に代入する形で定義する。こちらは通常の変数と同じ扱いになるため、定義より前に呼び出すとエラーになる
// 関数宣言:先に呼び出してもOK

'use strict';

{
  console.log(double(5)); // 呼び出しOK!

  function double(num) {
    return num * 2;
  }
}

function double(num)のような 関数宣言は、定義より前に呼び出してもエラーにならない。

// 関数式:先に呼ぶとエラー!

'use strict';

{
  console.log(double(5)); // エラー!double is not defined

  const double = function(num) {
    return num * 2;
  };
}

このように、関数式(constに代入する形)で定義された関数は、定義の前に呼び出すとエラーになる。

  • 最初は「関数宣言」を使うと安心
  • 「関数式」はアロー関数などとセットでよく使われる+“定義してから使う”が鉄則!
// 安心して使える関数宣言(初心者にやさしい)
function greet(name) {
  return `Hello, ${name}`;
}
console.log(greet("Alice"));

// 実務ではこちらが主流(アロー関数+関数式)
const greet = (name) => `Hello, ${name}`;
console.log(greet("Bob"));

//どちらも書けるようにしておく!!
  • 重要!:関数を引数に渡す「コールバック関数」
  • 「関数を引数に渡す」とは?
    関数の中で、別の関数を実行したい時に、引数として関数を渡すテクニック。「何をどう処理するか」を あとから決めたいときに便利
// コールバック関数:関数を引数に渡すことで、あとから処理内容を柔軟に決められる
const calc = (num, func) => {
  return func(num);
};

console.log(calc(20, (n) => n * 2)); // => 40
  • 「コールバック関数」は関数の“用途”の分類
  • 「アロー関数」は関数の“書き方”の一種

なぜ大事か?どこで使うか?
Web制作やJS実務で、以下のような場面で頻出。

用途 使われる場所の例
イベント処理 addEventListener("click", handler)
配列の処理 arr.map(func)forEach(func)
APIのレスポンス処理 fetch().then(response => {...})
アニメーション制御 setTimeout(() => {...}, 1000)
  • Q.何が一番使うのか?
    → 場面によって違うが、確実に使う頻度が高いのはアロー関数 + コールバック関数の組み合わせ である!
    この書き方は、React、jQuery、API操作、配列操作、アニメーション処理など、JS実務で“ほぼ確実に登場” する。
     
  • 関数編まとめ(感想)
    難しさは引き続き感じたが、見たことのあるコードが登場し、実務で'ここが特に使う'といったレベル感が整理できて良かった。あとから最も復習すべきセクションとなったかもしれない。

関数と構文を「合わせて使う」実務的な例

関数 ✕ if(条件によって処理を分けたい)

const greet = (name) => {
  if (!name) {
    return '名前がありません';
  }
  return `こんにちは、${name}さん`;
};

console.log(greet('太郎'));   // => こんにちは、太郎さん
console.log(greet(''));       // => 名前がありません
  • ifで条件分岐し、関数の中で動的に出力を変えてる例
  • フォーム入力チェックなど実務でよくあるパターン!

関数 ✕ for(繰り返しの処理をまとめたい)

const printScores = (scores) => {
  for (let i = 0; i < scores.length; i++) {
    console.log(`${i + 1}人目の点数: ${scores[i]}`);
  }
};

printScores([70, 80, 90]);
// => 1人目の点数: 70
// => 2人目の点数: 80
// => 3人目の点数: 90
  • forのループ処理を関数にまとめることで、再利用性UP!
  • 配列の値を順番に処理する基本中の基本

関数 ✕ forEach(配列の要素を順に処理)

const showFruits = (arr) => {
  arr.forEach((fruit, index) => {
    console.log(`${index + 1}個目の果物:${fruit}`);
  });
};

showFruits(['りんご', 'みかん', 'バナナ']);
// => 1個目の果物:りんご
// => 2個目の果物:みかん
// => 3個目の果物:バナナ
  • forEachは関数(アロー関数)を中に入れて使う構文
  • コールバック関数の練習にもなる!

JavaScript入門 データ構造編(全27回)

  • 配列の基礎
'use strict';

{
    const scores = [
        70,
        90, 
        80, 
        85,
        // 値を追加することもあるので、最後の値はカンマがあってもいい。
    ];

    console.log(scores[2]); //80
    console.log(scores.length); //個数。出力結果は4。
    scores[1] = 95;
    console.log(scores); // [70, 95, 80, 85]
}
  • length要素の個数 を表す
     
  • constの値を後から書き換えると通常はエラーになるが、配列の場合は例外で、後から書き換えが出来る。但しこの場合、const以外を使うと上手くいかないため注意!
     
  • 配列の末尾に要素を追加push、配列の末尾の要素を削除pop
  • 配列の先頭に要素を追加unshift、配列の先頭の要素を削除shift
    pushはよく使う。それ以外は必要に応じて復習する
     
  • for:配列の中身を順に取り出して処理する
'use strict';

{
    const scores = [
        70,
        90, 
        80, 
        85,
    ];

    scores.push(77, 88);

    // 要素取得
    // console.log(scores[0]);
    // console.log(scores[1]);
    // console.log(scores[2]);
    // console.log(scores[3]);
    // ↑ この意味を成すコードを、forで書く!

    for (let i = 0; i < scores.length; i++) {
        console.log(scores[i]);        
    }
    // `.length`の部分 → 定着させるべきオススメの書き方
    // (`i<4`とか書くよりも保守性が高い)
}
  • forEach:途中にアロー関数を使う。for文よりもコード量が少なく、配列の処理パターンとして“暗記必須”の書き方
'use strict';

{
    const scores = [
        70,
        90, 
        80, 
        85,
    ];

    scores.forEach((score, index) => {
    console.log(`${index}: ${score}`);
  });
}

forEachforの使い分け

  • forEachが向いている場面(9割以上のケース)
    • 商品一覧や画像ギャラリーなど、全てのデータを順番に表示する
    • ボタンなど複数要素に一括でイベントを追加する
    • ユーザー一覧やエラーメッセージなどを順にHTMLへ反映
    • 処理を途中で止める必要がないとき(break不可)
       
  • forが向いている場面(条件による制御が必要なとき)
    • 特定の条件でループを途中で止めたいbreakしたい)
    • 1個飛ばし・偶数番目だけ処理などの細かい制御が必要
    • 逆順でループしたい(後ろから処理したい)
       
  • 「配列を順に処理する」とは?
    • Web制作の実務で例えるなら:
    • 画像や商品などの一覧UIを自動で生成する
    • 全ボタンや要素にまとめてイベントをつける
    • APIから取得したデータをページ上に並べる
    • 複数のエラー文を一括で表示する
       
  • まとめると⇒
    • ほとんどの場面では forEach でOK!
    • UIパーツを複数処理するときは forEach
    • 特殊な処理をしたいときだけ for

forEachのインデックス(i)を使ったミニクイズ解説

const nums = [3, 2, 8];

nums.forEach((num, i) => {
  console.log(i * 3);
});
  • num:配列の中の値(3, 2, 8)
  • i:インデックス(何番目の要素か → 0, 1, 2)
     
  • 実行時の内容
i(インデックス) num(値) i * 3 出力される値
0 3 0 0
1 2 3 3
2 8 6 6
  • forEach((値, インデックス) => {...}) の形を覚えておくと便利!
  • 値だけ使うなら (num) => {...}
  • インデックスも使いたいときは (num, i) => {...}
    ※第2引数がインデックス(i)なのはforEach()など配列用のメソッドの時だけ。
     
  • 配列は[](角括弧)だったが、オブジェクトでは{}(波括弧)を使う
  • 値に名前をつけるには、それぞれの値の前に文字列を配置して、:で区切る。const scores = {math : 80, english : 90};
    →これがオブジェクトのリテラル表現で、これで1つの値になるので、定数に代入できる。mathenglishの部分を「キー」、8090の部分を「値」、「キー」「値」を合わせて「プロパティ」と呼ぶ。
     
  • プロパティへのアクセス、代入、追加、削除の方法
'use strict';

{
    const scores = {
        math: 80,
        english: 90,
    };
    console.log(scores.english); //プロパティへのアクセス
    scores.math = 88; //プロパティへの代入(ドットで繋げる)

    scores.physics = 70; //プロパティの追加(新しく'物理学'を追加)
    delete scores.english; //プロパティの削除('delete'を使う)
    console.log(scores);

    // 結果:90(scores.english)
    // math: 88
    // physics: 70
}
  • プロパティが増えた場合、配列の反復処理を使いたいところだが、オブジェクトに対して直接forEach()を使うことはできない → 一旦オブジェクトを配列に変換してから forEach()を使うというテクニックがある
'use strict';

{
  const scores = {
    math: 80,
    english: 90,
  };
  let sum = 0; // 合計を保持するための変数をsumで宣言し、0で初期化
  scores.physics = 70; // 物理学を追加

  // 今までのやり方:1つずつ取り出して表示(数が少ないとき)
  // console.log(scores.math);
  // console.log(scores.english);

  // プロパティ(キーと値)が増えたら毎回書くのが大変!
  // → Object.entries()で [キー, 値] の配列に変換し、forEachでまとめて処理
  const entries = Object.entries(scores);

  entries.forEach((prop) => {
  // 【復習:アロー関数】元々は
  // entries.forEach(function(prop) { のところを短く見やすく。
  // (prop)=プロパティ=['math', 80],['english', 90],

    sum += prop[1]; // 値(点数)を1つずつ足す → 合計にする

    console.log(`${prop[0]}: ${prop[1]}`); // math: 80、english: 90で表示
    //prop[0] → 'math'(キー)、prop[1] → 80(値)
  });
  console.log(`Sum: ${sum}`);
  console.log(`Average: ${sum / entries.length}`);
  // 毎回、合計と平均を表示(平均=合計 ÷ 科目数)
  // 結果:math: 80、english: 90、physics: 70、Sum: 240、Average: 80

  // 合計(Sum)と平均(Average)は、ループの外でまとめて表示する
  // → forEachの中に書いてしまうと「途中経過」が毎回表示されてしまう!
  // ex)1回目の合計、2回目の合計、…と何度も表示されてしまうため、
  // 「最終結果」を見たいときはループを抜けたあとに表示する。
}
  • 配列の先頭や末尾の要素を操作するにはpushpopunshiftshiftがあったが、途中の要素を挿入・削除する場合これらは使えず、代わりにsplice()を使う。splice(➀変化する位置のインデックス[0][1][2].., ➁削除する要素の数, ➂追加する要素1, ➃追加する要素2...);
'use strict';

{
  const scores = [70, 90, 80, 85];

  scores.splice(2, 0, 77, 88);
  // splice(➀変化する位置のインデックス[0][1][2]..,
  // ↑ 上記の場合、[2]なら80の前を指す。
  // ➁削除する要素の数(0), ➂追加する要素1(77), ➃追加する要素2(78)...);
  // [70, 90, 77, 88, 80, 85];

  const deleted = scores.splice(3, 1);
  // [70, 90, 77, 88, 80, 85];から開始。
  // splice(➀変化する位置のインデックス[3] = 88,
  // ➁削除する要素の数(1));
  // [70, 90, 77, 80, 85];
  // 削除された[88]が delited に代入される。

  scores.splice(2, 2, 30);
  // [70, 90, 77, 80, 85];から開始。
  // splice(➀変化する位置のインデックス[2] = 77,
  // ➁削除する要素の数(2) → 77, 80を指す。
  // ➂追加する要素1(30));
  // // [70, 90, 30, 85];

  console.log(scores); // [70, 90, 30, 85]
  console.log(deleted); // [88]
}
  • 要素を「|」で区切って表示させたい時は、join('|') を使う。 カンマで区切って表示させたい時は、引数なしの join()(=デフォルトでカンマ区切りになる)を使う。 区切らずに繋げたい時は、join('') と書く
  • 逆に、文字列を配列にしたい場合はsplit() を使う(例:split('|')
'use strict';

{
  // const names = ['Taro', 'Jiro', 'Saburo'];
  // 要素を|で区切って表示させたい時
  // console.log(names.join('|')); // Taro|Jiro|Saburo
  // 要素をカンマで区切って表示させたい時
  // console.log(names.join()); // Taro,Jiro,Saburo
  // |でもカンマでも区切らず繋げたい時
  // console.log(names.join('')); // TaroJiroSaburo

  // 逆に文字列から配列を作りたい時
  const names = 'Taro|Jiro|Saburo';
  console.log(names.split('|')); // ['Taro', 'Jiro', 'Saburo']
}
  • 配列の中身を1つずつ加工して「新しい配列」を作りたい時はmap()を使う(加工の例:税込価格に変換、名前に「さん」を付ける など)
'use strict';

{
  const prices = [100, 150, 200];
  // // それぞれを10%の税込み価格にした配列を別途用意する
  // const pricesWithTax = [];
  // prices.forEach((price) => {
  //   pricesWithTax.push(price * 1.1);
  // }); //上記を簡潔に書くためにmap()を使う

  const pricesWithTax = prices.map((price) => {
    return price * 1.1;
  });

  console.log(pricesWithTax);
  // ある配列の各要素を処理して新しい配列を作る場合、
  // map() のほうが簡潔に書けるのでこちらを好む人も多い
}
  • 配列から「条件に合う要素だけ」を取り出して新しい配列を作りたい時はfilter()を使う(例:150円以上の商品だけ、偶数だけ、指定文字列を含む要素だけ、など)
'use strict';

{
  const prices = [100, 150, 200];
  // 150円以上の価格だけを抽出し、これとは別の新しい配列を作りたい時
  // const pricesOver150 = [];
  // prices.forEach((price) => {
  //   if (price >= 150) {
  //     pricesOver150.push(price);
  //   }
  // }); //上記を簡潔に書くためにfilter()を使う

  const pricesOver150 = prices.filter((price) => {
    return price >= 150; // 条件に合う要素だけを新しい配列に入れる
  });

  console.log(pricesOver150); // [150, 200]
}
  • map → 元の配列の各要素を処理して同じ要素数の配列を返す
  • filter → 元の配列の値はそのままに条件に合致するものだけを抽出する
     
  • 分割代入:配列の代入を短く書ける
'use strict';

{
  const scores = [70, 90, 80, 85];
  // これらの値をこの後のコードでよく使うことになったので、
  // それぞれに分かりやすい定数名を付けたくなったとする。
  // const first = scores[0];
  // const second = scores[1];
  // const third = scores[2];
  // const fourth = scores[3];
  // ↑これを一気にスッキリ書ける!!
  const [first, second, third, fourth] = scores;
  // 新しく配列を作るコードではない。これは分割代入!混同注意!
  console.log(first);
  console.log(second);
  console.log(third);
  console.log(fourth);
}
  • 分割代入の値の入れ替え
'use strict';

{
  let start = 'Tokyo';
  let goal = 'Osaka';

  // 【値を入れ替える目的】
  // ランキングの順位を入れ替える必要があるように、
  // 「逆ルートで行きたい!」という希望からスタートとゴールを逆にする処理が必要になることもある。
  // 表示順を変えたい時や、条件に応じて中身を交換したい時に使われる。

  // 【今までのやり方】
  // 一時変数 temp を使って、startとgoalの値を入れ替えていた
  // let temp = '';
  // temp = start;
  // start = goal;
  // goal = temp;

  // 【分割代入を使った入れ替え】
  [goal, start] = [start, goal];

  // ↓ どういうこと?イメージ図
  // [goal, start]      = [  'Tokyo',   'Osaka' ]
  //    ↑  ↑                  ↑           ↑
  //   goal ← start      start ← goal
  // → つまり、お互いの値を同時に入れ替えている!

  console.log(start); // 'Osaka'
  console.log(goal);  // 'Tokyo'
}
  • スプレッド構文+レスト構文 ※rest=「残り」
  • レスト構文:受け取って1つにまとめる → "左辺"に使う。const [first, ...others]
    スプレッド構文:広げて展開する → "右辺"に使う。[70, 90, 80, 85, ...moreScores];どちらも...がポイント
'use strict';

{
  const moreScores = [77, 88];

  // 【スプレッド構文】配列の中身(要素)を "展開" して、別の配列に入れる
  // → moreScoresの[77, 88]をscoresの末尾に展開して入れる
  const scores = [70, 90, 80, 85, ...moreScores];

  // 【分割代入】配列の最初の1つだけをfirstに、
  // 残りすべてをothersという1つの配列にまとめて受け取る
  // → 「残り全部まとめて」受け取る構文が【レスト構文】(...others)
  const [first, ...others] = scores;

  console.log(first);   // 70(最初の1つだけ)
  console.log(others);  // [90, 80, 85, 77, 88](残りすべてをまとめて配列に)
  • プリミティブ型(基本データ型) vs 配列(オブジェクト)代入時の挙動の違い:プリミティブ型 は「値そのもの」がコピーされるので、後から変更しても元の値には影響しない
  • 一方、配列やオブジェクト は「参照(アドレス)」がコピーされるため、片方を変更するともう片方にも影響する。 しっかり複製したいときは、スプレッド構文などで「中身ごとコピー」する必要がある
'use strict';

{
  // プリミティブ型
  // let num = 10;
  // const numBackup = num; // ← 中身「10」をそのままコピー
  // num = 99;
  // console.log(num);       // 99(上書きしたから)
  // console.log(numBackup); // 10(コピー元とは別物!)

  // 上記処理を配列で行うと...
  // const nums = [10, 20, 30];
  // const numsBackup = nums; //← 中身じゃなく、「場所」をコピー
  // nums[0] = 99;
  // console.log(nums);// [99, 20, 30]
  // console.log(numsBackup); // [99, 20, 30]。← あれ、変わっちゃってる!

  // コピーしたいときはスプレッド構文!
  const nums = [10, 20, 30];
  const numsBackup = [...nums]; // ← これで中身をコピーできる!
  nums[0] = 99;
  console.log(nums);       // [99, 20, 30]
  console.log(numsBackup); // [10, 20, 30] ← ちゃんと別物!
}
  • データ構造編まとめ(感想)
    配列の表示方法の様々なパターンや代入のルールなど、コードを書く上で必須となる知識が詰まっていたセクションだった。しっかりと記憶に刻み込みたい。

JavaScript入門 DOM編(全22回)

  • DOM(Document Object Model):画面の描画と連動し、コード編集を行ったら、その変更が即座に画面へ反映される仕組み
  • 基本的にDOM操作では要素(p要素,section要素など)を取得した後にその要素を操作(テキストやスタイルを変更)するという構造になっている
     
  • querySelector('セレクタ') を使うと、特定のHTML要素をJavaScriptから取得できる
    例:'p', '.class名', '#id名' などのCSSセレクタを指定
  • .addEventListener('click', () => {...}) を使うと、クリックなどのイベントに処理を追加できる
    例:ボタンを押したら文字を変える、色を変える、非表示にする…等の動作を定義できる
  • .textContent プロパティを使うと、要素の中のテキストを変更できる
'use strict';

{
    document.querySelector('button').addEventListener('click', () => {
        // console.log('Clicked');
        document.querySelector('p').textContent = 'こんにちは';
        // コンソール画面ではなく、pタグでちゃんと画面に文字列を表示させる
        // OKボタンを押すと'Hello'が'こんにちは'に変わる処理が行われる
    });
    // querySelector('')の中に
    // 取得したい要素を選択するための
    // CSSセレクターを文字列で渡す

    // addEventListener()の中に
    // ➀'イベントの種類',
    // ➁アロー関数でクリックした時に処理したい内容
    // () => {処理内容};
    // 2種類を入れる

    // ここまで書くと、ボタンを押し、
    // コンソールに「Clicked」と表示される仕組みが完成する

    // console.log('Hello');
}
  • ボタンをクリックしたらスタイルが変わる,スタイル操作用:classList
  • 要素のスタイルを変更するには、CSSでクラスを定義してから、classList を使う。クラス追加:classList.add、クラス削除:classList.remove
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My JavaScript</title>
    <style>
        .pink-bg {
            background: pink;
        }

        .red-border {
            border: 2px solid red;
        }

        .green-color {
            color: green;
        }
    </style>
</head>
<body>
    <p class="green-color">Hello</p>
    <button>OK</button>
    <script src="./main.js"></script>
</body>
</html>
'use strict';

{
    document.querySelector('button').addEventListener('click', () => {
       document.querySelector('p').classList.add('pink-bg', 'red-border');
       document.querySelector('p').classList.remove('green-color');
    //  p要素を取得し、クラスを追加するためにclassList.addとする。
    // ()内:p要素に追加したいクラス名 ※先頭の.(ドット)は要らない!!
    // ,(カンマ)区切りで複数渡せる。
    // 削除したいクラスはclassList.removeとする。
    });
}
  • クラスの切り替え(ON/OFF)には classList.toggle が便利
  • 上記コードのように .add() / .remove() を使うと、「追加」「削除」を明確に制御できる一方、同じクラスをON/OFFしたいだけなら toggle() を使うと簡潔に書ける!
'use strict';

{
  document.querySelector('button').addEventListener('click', () => {
    document.querySelector('p').classList.toggle('pink-bg');
    // クラスがなければ追加、あれば削除(ON/OFFの切り替え)
  });
}
  • 補足:toggle() を使わずに if文で切り替えることもできる
  • classList.contains('クラス名') は、そのクラスを持っているかどうか判定するのに便利
  • ↓このように条件分岐で書けば、切り替え時の処理を柔軟にカスタマイズできる!
'use strict';

{
  document.querySelector('button').addEventListener('click', () => {
    if (document.querySelector('p').classList.contains('pink-bg') === false) {
      document.querySelector('p').classList.add('pink-bg');
    } else {
      document.querySelector('p').classList.remove('pink-bg');
    }
    // クラスの有無を確認し、自分で制御したいときはこのように書く
  });
}

☆ classListの使い分け早見表

メソッド 主な用途 よくある使用シーン例
classList.add() クラスを追加 ✅ ボタンを押したら表示状態にする(例: モーダル表示)
classList.remove() クラスを削除 ✅ ボタンを押したら非表示にする(例: 閉じるボタン)
classList.toggle() クラスのON/OFFを自動で切り替える ✅ ボタン1つで表示/非表示を交互に切り替えたいときなど
classList.contains() クラスを持っているかどうか確認する ✅ 状況によって処理を分けたいとき(ON/OFFで挙動が違う場合)

☆補足:どれを使えばよいか?

  • add/remove → 「ONにする or OFFにする」どちらか一方だけの操作を明示したいときに使う
     (例:「開くときだけ処理したい」「消すだけのボタン」など)
  • toggle → 状態を毎回切り替えるだけでOKなときに使う
     (例:「開く⇔閉じる」を1ボタンでやりたいとき)
  • contains → 今の状態を見て条件分岐させたいときに使う
     (例:「開いている時だけこの処理をしたい」など)
     
  • 複数の要素を取得するには、document.querySelectorAll() を使う
  • これで取得されるのは、「配列のように並んだリスト」 なので、1つずつ処理するために forEach() を使う必要がある
  • .textContentなどをまとめて直接使おうとするとエラーになる(1つずつアクセスする必要がある)
<body>
    <ul>
        <li>Taro</li>
        <li>Jiro</li>
        <li>Saburo</li>
    </ul>
    <button>OK</button>
    <script src="./main.js"></script>
</body>
'use strict';

{
  document.querySelector('button').addEventListener('click', () => {
    document.querySelectorAll('li').forEach((li) => {
      // 複数の要素を処理する場合(この場合はリストの3項目)、
      // querySelectorAll()とforEach(反復処理)を組み合わせる必要がある
      li.textContent = 'Changed!'; // Taro,Jiro,Saburoが同時に「Changed!」に
    });
  });
}

querySelector vs querySelectorAll 使い分け早見表
getElementById()も存在するが、書き方としてもう古い上にforEachが使えないので、今後は使わないほうがよい!!

メソッド 主な用途 使い方の特徴
querySelector() 1つ目の要素だけ取得したいとき CSSセレクタ形式で指定。1個だけ対象。
querySelectorAll() 複数の要素すべてを取得したいとき forEach() などで1つずつ処理する。
  • 特定の要素の取得
<body>
    <ul>
        <li class="target">Taro</li>
        <li id="second">Jiro</li>
        <li class="target">Saburo</li>
    </ul>
    <button>OK</button>
    <script src="./main.js"></script>
</body>
'use strict';

{
  document.querySelector('button').addEventListener('click', () => {
    document.querySelectorAll('.target').forEach((li) => {
      // 特定のリストだけ取得したい場合、
      // その項目のHTMLにクラス名(今回は.target)を付けて、
      // js側をquerySelectorAll('.target')とする。
      // ※予備で付けたID('#second')のみ動かすことも可。
      li.textContent = 'Changed!';
    });
  });
}

☆HTMLを編集しなくても、jsのDOM操作だけで要素を追加できる

  • createElement('li'):新しいliタグを生成する
  • appendChild():親要素の末尾(1番最後) に追加する
  • insertBefore():親要素内の指定した要素の前に追加する
  • confirm():ユーザーに確認ダイアログを表示
'use strict';

{
  document.querySelector('button').addEventListener('click', () => {
    // 新しい <li> 要素を作成する
    const liElement = document.createElement('li');

    // テキストを設定
    liElement.textContent = 'Hanako';

    // ▼ 要素の追加パターン①:末尾に追加(appendChild)
    // 実行結果:Taro → Jiro → Saburo → Hanako(←いちばん最後に追加される)
    // document.querySelector('ul').appendChild(liElement);

    // ▼ 要素の追加パターン②:指定した要素の「直前」に追加(insertBefore)
    // 実行結果:Taro → Hanako → Jiro → Saburo(←Jiroの前に割り込む)
    // 第1引数:追加したい要素(liElement)
    // 第2引数:目印となる要素(ここでは「Jiro」)
    // document.querySelector('ul').insertBefore(
    //   liElement,
    //   document.querySelector('#second')
    // );

    // ▼ 要素の削除(確認ダイアログでOKを押すと「Jiro」が消える)
    if (confirm('Sure?') === true) {
      document.querySelector('#second').remove();
    }
  });
}
  • フォーム部品の値は.value で取得,変更ができる(例:テキストフォームの内容やドロップダウンリストなど)
<body>
    <!-- <input type="text"> -->
     <textarea></textarea>
    <button>OK</button>
    <script src="./main.js"></script>
</body>
'use strict';

{
  document.querySelector('button').addEventListener('click', () => {
    // alert(document.querySelector('input').value);
    // ↑ textContentではない!!
    // フォーム部品の値にアクセスするにはvalueを使う!!
    // 結果:OKボタンを押すと、
    // テキストフォームに入力した内容のアラートが出せる。

    document.querySelector('textarea').value = '';
    // ''の部分=空文字を代入→
    // ボタンをクリックしたらtextareaの中の値がクリアされる
  });
}
  • フォーム部品の値 取得:注意➀!テキストフォームの値やドロップダウンリストは querySelectorで取得できるが、ラジオボタンの場合は querySelectorAllforEach を使う必要がある!!(また、HTMLのinputタグ内はname属性が要る!!)
  • 理由:ラジオボタンは、見た目は1つの選択肢に見えても、HTML上は個別の<input>タグの集合体。そのため、「複数ある中からどれが選ばれているか」を調べるには、1つずつchecked状態を判定する必要がある!
'use strict';

{
  document.querySelector('button').addEventListener('click', () => {
    // すべてのラジオボタンを取得してループ処理
    document.querySelectorAll('input').forEach((radio) => {
      // checked === true なら選択されているラジオボタン
      if (radio.checked === true) {
        alert(radio.value); // 選ばれた値をアラートで表示
      }
    });
  });
}
  • フォーム部品の値 取得:注意②!チェックボックスの場合も querySelectorAllforEach を使う必要があるが、さらにここでは配列処理,pushjoinも組み合わせる!
  • 理由:チェックされた項目の数だけアラートが表示されてしまうため!!
  • +選ばれた値を一括で表示するには push() で配列にためて、join() で文字列にまとめるのがベストなため
'use strict';

{
  document.querySelector('button').addEventListener('click', () => {
    const colors = []; // 複数の値を保持するために配列を使う
    // 空の配列で初期化する
    document.querySelectorAll('input').forEach((checkbox) => {
      if (checkbox.checked === true) {
        colors.push(checkbox.value);
      }
    });
    alert(colors.join(','));
    // 反復処理が終わったら、アラートで colors の値を文字列にして表示
    // 色の名前の間にカンマ(チェックした色 → red,green と出る。)
  });
}

☆実用的な例!inputイベントで、入力した文字を文字数カウント

  • これまでの例では「ボタンを押したとき」に .value を取得していたが、inputイベントでは入力のたびにリアルタイムで値の変化を監視できる
  • つまり、「値をいつ取得するか」の違いがあり、input即時反応が必要な場面(例:文字数カウントやバリデーション) に最適
<body>
  <input type="text">
  <p></p> 
  <script src="main.js"></script>
</body>
'use strict';

{
  // 入力欄に文字が入力されるたびにイベントが発火
  // ▼ イベントの使い分け:'input'は text や textarea に使うイベント
  // 'change'はラジオやチェックボックス用
  document.querySelector('input').addEventListener('input', () => {
    const pElement = document.querySelector('p');           // 結果を表示するpタグ
    const inputElement = document.querySelector('input');   // 入力されたテキスト

    // 入力文字そのものを表示する場合はこちら
    // pElement.textContent = inputElement.value;

    // 文字数だけを表示する
    pElement.textContent = inputElement.value.length;
  });
}
}

☆補足:イベントの使い分け(input / change)inputイベントとchangeイベントはどちらもフォーム入力の変化に反応するが、使い分けが必要

  • inputイベント:文字入力中にもリアルタイムで反応(例:テキストやテキストエリア)
  • changeイベント:選択が確定されたときに反応(例:ラジオやチェックボックス)
フォーム部品 イベントタイプ 説明(いつ反応するか)
テキスト入力欄 input 入力するたびに即時反応
テキストエリア(複数行入力) input 入力するたびに即時反応
プルダウンリスト input/change 選択肢を変更した瞬間(inputでもOK)
ラジオボタン change 選択肢をクリックして変更した時のみ
チェックボックス change チェック/解除をした瞬間
  • (テキストフォームに)フォーカスを当てた時の動作用:focusイベント
  • フォーカスを外した時の動作用:blur(ブラー)イベント
  • ページを読み込んだと同時にフォーカスを当てておく動作用:focus()イベント
    ※用途によって記述位置が異なるので注意!!
'use strict';

{
  document.querySelector('input').addEventListener('focus', () => {
    // フォーカスを当てた時の動作
    document.querySelector('p').textContent = 'English only!'; // メッセージ表示
  });

  document.querySelector('input').addEventListener('blur', () => {
    // フォーカスを外した時の動作
    document.querySelector('p').textContent = ''; // テキストフォームの文字を消す
  });

  // ページを読み込んだと同時にフォーカスを当てておく動作
  document.querySelector('input').focus();
}

keydownイベント:どのキーが押されたか取得する

  • 文章全体に対してイベントリスナーを設定したい場合、documentに対して直接 addEventListener する
  • 引数名は何でもよいが、一般的にイベントのeが使われる
  • e.key は、キーボードで押されたキーの“名前(文字列)”を取得できるプロパティで、 例えば「a」キーを押すと "a"、「Enter」キーを押すと "Enter" という文字列が返される。この値をp要素の textContentに代入すれば、ユーザーが押したキーの内容をそのまま画面に表示することができる
  • この仕組みは、左右キーでスライドを切り替える画像ギャラリーや、Enterキーでフォームを送信する機能W/A/S/Dキーでキャラクターを動かすゲームなど画面を動かすUIに応用できる
<body>
  <p></p>
  <script src="main.js"></script>
</body>
'use strict';

{
  document.addEventListener('keydown', (e) => {
    document.querySelector('p').textContent = e.key;
  });
}

mousemoveイベント:マウスの動きを追って、X座標/Y座標の位置を表示

  • e.clientX / e.clientY:マウスカーソルが、ブラウザの表示領域(ビューポート)の中でどこにあるかを「X座標(横)」「Y座標(縦)」として数値で返すプロパティ
  • お絵かきツールや、マウスで動かすゲームを作れる
プロパティ 何の値? 単位
e.clientX ブラウザ左上からの横方向の位置 px X: 100 → 左から100pxの位置
e.clientY ブラウザ上端からの縦方向の位置 px Y: 200 → 上から200pxの位置
'use strict';

{
  document.addEventListener('mousemove', (e) => {
    document.querySelector('p').textContent = `X: ${e.clientX} Y: ${e.clientY}`;
    // ':'(コロン)があるのでテンプレートリテラルを使う
  });
}

submitイベント:HTMLに記入したformタグ内のフォームに入力した文章をフォームの下に表示できる。ただし、再読み込みによるフォームデータ削除を防ぐため、submitイベントを使う際は必ずe.preventDefault();(ブラウザの“標準の動作”をキャンセル)を記述すること
→ ユーザーにとって自然な操作(Enter送信など)を活かしたいなら、formsubmitpreventDefaultが基本パターン!

処理したいこと どうする?
入力内容を送信せず画面に表示 submit イベント+preventDefault()
Enterキーで送信させたい <form> タグを使う
<body>
  <form>
    <input type="text">
    <button>OK</button>
  </form>
  <p></p>
  
  <script src="main.js"></script>
</body>
'use strict';

{
  document.querySelector('form').addEventListener('submit', (e) => {
    // ページの再読み込みを防ぐ
    e.preventDefault();

    // 入力欄の値をpタグに表示
    document.querySelector('p').textContent = document.querySelector('input').value;
    // 【復習】.value:inputタグの中に入力された値(文字列)を取得するためのプロパティ
  });
}

重要トピック➀:「属性操作」

🔰「属性操作」とは?

  • HTML要素には、srchref のような「属性」がある。これらの値を JavaScriptから直接書き換えることで、表示や挙動を動的に変更できる

✏️ 基本ルール

  • 属性操作の基本は、要素.属性名 = 値;
<img src="dog.png">
<a href="https://dotinstall.com">リンク</a>
// src属性の書き換え(画像切り替え)
document.querySelector('img').src = 'cat.png';

// href属性の書き換え(リンク先の変更)
document.querySelector('a').href = 'https://256times.com';
  • HTMLで使われている属性名(src、hrefなど)と同じ名前のプロパティを使うのが基本!

⚠️ 注意が必要な「3つの属性」

class属性は .class ではなく .className を使う

  • class は JavaScript の予約語のため、プロパティ名としては使えない
// ↓これは構文エラーになる
// element.class = 'red-border';
// 正しくは className を使う
element.className = 'red-border';  // ※既存のクラスを上書きしてしまう
  • 既に他のクラス(例:pink-bg)が付いている場合は、空白で区切って全て書く必要あり
element.className = 'pink-bg red-border';
  • ✅推奨:classList.add() を使う!
element.classList.add('red-border');
  • 既存のクラスにそのまま追加される
  • .remove().toggle()も使える
  • 今までの学習で使っていた方法。基本はこちらを使えばOK

disabled/checked/selectedtrue/falseで制御する

  • これらは「ある/なし」で状態を表す属性
<button disabled>OK</button>
  • ↑これを JS で制御するには:
const btn = document.querySelector('button');
btn.disabled = true;  // ボタンを無効にする
btn.disabled = false; // ボタンを有効にする
  • 同様に:
checkbox.checked = true;   // チェックをつける
option.selected = true;    // セレクトで選ばれた状態にする
  • ✅ これらは 「状態属性」 と呼ばれ、true/falseで操作するのが基本ルール。

checkedの補足:以前は「取得」だけを使っていた

// チェックされているラジオボタンを取得
if (radio.checked === true) {
  alert(radio.value);
}
  • → ここでは.checked状態の確認(読み取り)として使っていた
  • .checked = trueのように状態の操作(書き込み) として使う方法が登場
    .checkedは「取得と設定の両方ができる」プロパティ!

☆まとめ:属性操作の基本早見表

属性 操作例 説明
src img.src = 'cat.png' 画像の切り替え
href a.href = 'https://〜' リンク先の変更
className p.className = 'a b' クラス名を一括で上書き
classList p.classList.add('c') クラスを追加(推奨)
disabled btn.disabled = true / false ボタンの有効/無効を切り替え
checked checkbox.checked = true チェックを付ける
selected option.selected = true セレクトボックスの選択状態にする

☆補足:この章で新たに出てきたキーワード

キーワード 出現タイミング 覚え方/メモ
.className 初登場(class属性操作) 基本は classList、上書き時のみ使用
.disabled 初登場 状態属性 → true/falseで切り替え
.selected 初登場 セレクトボックスで選択状態を設定
.checked 既出(取得)→今回で「設定」も可 状態の取得/設定どちらもできる

重要トピック②:「style属性」

  • element.styleは、HTMLのstyle属性を直接操作できるプロパティ
  • CSSと異なり、プロパティ名はキャメルケース(小文字始まり+単語区切りは大文字) で書く。※例:font-sizefontSizebackground-colorbackgroundColor
  • ⚠️ element.style = 'font-size: 24px' のような書き方はエラーにはならないが無効
    → styleは「オブジェクト」なので、個別のプロパティに代入する形でしか使えない
  • style.fontSize = '24px'のように、文字列として値(単位付き)を代入すればOK。※動的にスタイルを変更したい場面(文字サイズの調整・背景色の切り替えなど)で使う

☆style変更の代表例(対応表)

CSSでの記述 JSでの書き方
color: red; element.style.color = 'red'
font-size: 24px; element.style.fontSize = '24px'
background-color: #ccc; element.style.backgroundColor = '#ccc'
border-radius: 8px; element.style.borderRadius = '8px'
<body>
  <p style="color: red;">Hello</p>
  <button>OK</button>
  
  <script src="main.js"></script>
</body>
'use strict';

{
  document.querySelector('button').addEventListener('click', () => {
    // document.querySelector('p').style = 'font-size: 24px';
    document.querySelector('p').style.fontSize = '24px';
  });
}
  • DOM編まとめ(感想)
    ここまでで最も実用的で、パターンごとに様々な書き方があるなあ、後から見返して使えたら嬉しいな、とのんびりまとめていたら、最後で新知識が怒涛の勢いで登場して混乱。細かいところは継続して詰めるとして、これでなんとか、JavaScript基礎習得セットになっただろうか。学ぶ意欲を絶やさず、このままどんどん深く知識の沼に潜っていきたい。
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?