学ぶ|Web開発入門 #6

JavaScriptの基本を独学で身につける完全ガイド|変数・関数・イベント・DOM操作まで

  • JavaScript
  • DOM
  • Web開発入門
  • プログラミング未経験

📋 この記事の目次
  1. JavaScriptは「呼び鈴を待つ受付係」だと考える
  2. Part A: JavaScriptの基本構文
  3. Part B: 関数
  4. Part C: イベント駆動型プログラミング
  5. Part D: DOM操作
  6. Part E: ロジック制御と配列操作
  7. Part F: 応用機能
  8. Part G: ベストプラクティス
  9. 実践プロジェクト:自己紹介カードに動きをつける
  10. 🧠 理解度チェック(一部抜粋)
  11. 挫折ポイントTOP3と対処法
  12. この先、何を学べばいいか
  13. まとめ
  14. 🎓 理解度テスト

これまでHTML/CSSで見た目を作り、Django+SQLでデータを保存できるようになりました。しかしまだ、ページの中身を変えるには「サーバーに問い合わせて、ページ全体を再読み込みする」しかありません。今回はJavaScriptで、ページを再読み込みせずにその場で表示を変える動きをつけます。

「HTML/CSSまでは理解できたのに、JavaScriptだけ急に難しく感じる」

その理由の多くは、JavaScriptが 「ユーザーの操作をきっかけに動く」 という、それまでとは違う考え方をする言語だからです。自己紹介カードに「ダークモード切替ボタン」と「スキル検索欄」を足しながら、この考え方を掴んでいきましょう。


JavaScriptは「呼び鈴を待つ受付係」だと考える

  • HTML/CSSは「あらかじめ決められた見た目」を作る係
  • Pythonのスクリプトは「上から順番に実行される」処理
  • JavaScriptは「何かが起きるのを待ち、起きたら反応する」 受付係

ボタンが押される、文字が入力される、ページの読み込みが終わる。こうした「出来事(イベント)」が起きるたびに、あらかじめ登録しておいた処理が呼び出される、という仕組みです。これをイベント駆動型プログラミングと呼びます。

🧓 ベテランの現場コラム 「上から順番に実行される」という感覚のままJavaScriptを書き始めると、「ボタンを押した後に実行されるはずの処理が、ページ読み込み時にいきなり動いてしまう」というつまずきが起こりがちです。JavaScriptの多くの処理は「未来のどこかで起きるイベントの予約」だと捉え直すと、動きが読めるようになります。


Part A: JavaScriptの基本構文

JavaScriptとは・Web開発の全体像

HTMLが構造、CSSが見た目だとすれば、JavaScriptは「ふるまい」を担当します。ブラウザ上で動く数少ない言語のひとつで、ボタンのクリックやフォームの入力チェックなど、ページに動きをつける役割を持ちます。

変数(let, const, var)

let darkMode = false;       // 再代入する可能性がある値
const skillList = ["Python", "SQL", "Git"];  // 再代入しない値(推奨)

現在はconstを基本にし、値を変える必要がある場合だけletを使うのが主流です。varは古い書き方で、意図しない範囲まで影響してしまう性質があるため、新しく書くコードでは使いません。

データ型と型の自動変換

console.log(typeof "文字列");   // "string"
console.log(typeof 42);        // "number"
console.log(typeof true);      // "boolean"

console.log("3" + 1);   // "31"(文字列として連結される)
console.log("3" - 1);   // 2(数値として計算される)

JavaScriptは+演算子が「文字列の連結」と「数値の足し算」の両方を兼ねているため、型を意識しないと意図しない結果になることがあります。


Part B: 関数

関数の定義とアロー関数

function toggleDarkMode() {
  document.body.classList.toggle("dark-mode");
}

const filterSkills = (keyword) => {
  return skillList.filter((skill) => skill.includes(keyword));
};

functionを使う書き方と、() => {}で書く「アロー関数」は、基本的には同じ「処理をひとまとめにしたもの」ですが、アロー関数の方が短く書けるため、近年はよく使われます。

スコープ

function example() {
  const localValue = "この関数の中だけで有効";
  console.log(localValue);
}
// console.log(localValue); // ここではエラー:関数の外からは見えない

変数が「どこまで見えるか(有効な範囲)」をスコープと呼びます。むやみに全体で使える変数を増やすと、どこで値が変わったか追いづらくなるため、必要な範囲だけに変数を閉じ込めるのが基本です。


Part C: イベント駆動型プログラミング

イベントハンドラの設定とイベントオブジェクト

const darkModeButton = document.getElementById("dark-mode-toggle");

darkModeButton.addEventListener("click", (event) => {
  console.log(event.target); // クリックされた要素そのものが渡ってくる
  toggleDarkMode();
});

addEventListenerは「このボタンがクリックされたら、この処理を実行してください」という予約です。event(イベントオブジェクト)には、何がどう操作されたかの情報が詰まっています。

デフォルト動作の無効化(preventDefault)

const searchForm = document.getElementById("skill-search-form");

searchForm.addEventListener("submit", (event) => {
  event.preventDefault(); // ページの再読み込みを止める
  const keyword = document.getElementById("skill-search-input").value;
  renderFilteredSkills(keyword);
});

フォームは本来「送信するとページが再読み込みされる」動作がデフォルトですが、preventDefault()でその動作を止め、代わりにJavaScriptで表示だけを書き換えることができます。


Part D: DOM操作

DOMとは・要素の選択

DOM(Document Object Model)は、ブラウザがHTMLを「操作できる木構造のデータ」として扱う仕組みです。JavaScriptはこのDOMを通じて、画面の内容を書き換えます。

const skillListElement = document.querySelector(".skill-gallery");
const allSkillCards = document.querySelectorAll(".skill-card");

コンテンツ・スタイルの操作、要素の作成と追加

function renderFilteredSkills(keyword) {
  const filtered = filterSkills(keyword);

  skillListElement.innerHTML = ""; // 一旦空にする

  filtered.forEach((skill) => {
    const card = document.createElement("div");
    card.className = "skill-card";
    card.textContent = skill;
    card.style.backgroundColor = "#eef2ff";
    skillListElement.appendChild(card);
  });
}

createElementで新しい要素を作り、appendChildでページに追加する。この一連の流れが「JavaScriptでページの中身を動的に書き換える」基本操作です。

🧓 ベテランの現場コラム innerHTMLは便利ですが、ユーザーの入力値をそのままinnerHTMLに流し込むと、悪意あるコードが実行されてしまう危険(クロスサイトスクリプティング、XSS)があります。9回目のセキュリティ回で詳しく扱いますが、「表示する内容の出どころ」を常に意識する癖を今のうちからつけておきましょう。


Part E: ロジック制御と配列操作

条件分岐・ループ

if (filtered.length === 0) {
  console.log("該当するスキルがありません");
} else {
  console.log(`${filtered.length}件見つかりました`);
}

for (const skill of skillList) {
  console.log(skill);
}

配列メソッド

const upperSkills = skillList.map((skill) => skill.toUpperCase());
const longSkills = skillList.filter((skill) => skill.length > 3);
const hasSql = skillList.some((skill) => skill === "SQL");
const allString = skillList.every((skill) => typeof skill === "string");

map(変換)・filter(絞り込み)・some/every(条件を満たすか判定)は、forループを何度も書く代わりに使える定番の配列操作です。スキル検索欄も、内部的にはこのfilterを使っています。


Part F: 応用機能

オブジェクト・テンプレートリテラル・分割代入

const visitorComment = {
  name: "山田花子",
  message: "参考になりました",
};

const { name, message } = visitorComment; // 分割代入
console.log(`${name}さんからのコメント: ${message}`); // テンプレートリテラル

エラー処理とコンソール操作

try {
  JSON.parse("{ 不正なJSON");
} catch (error) {
  console.error("JSONの解析に失敗しました", error);
}

console.logだけでなく、警告にはconsole.warn、エラーにはconsole.errorを使い分けると、開発者ツールでの確認がしやすくなります。

外部JavaScriptファイル

<script src="script.js" defer></script>

defer属性をつけると、HTMLの読み込みを妨げずに、かつHTML全体の解析が終わってからJavaScriptを実行してくれます。「要素が見つからずエラーになる」という初心者にありがちな事故を防げます。


Part G: ベストプラクティス

  • DRY原則(Don’t Repeat Yourself): 同じ処理を複数箇所にコピペせず、関数にまとめる
  • 命名規則: 変数・関数はcamelCase(例: toggleDarkMode)で統一する
  • コメント: 「何をしているか」ではなく「なぜそうしているか」を書くと後で役立つ

実践プロジェクト:自己紹介カードに動きをつける

  1. ダークモード切替ボタンを設置し、クリックでbodyにクラスを付け外しする
  2. スキル検索欄を作り、入力のたびにfilterで絞り込んだ結果を表示する
  3. フォーム送信時はpreventDefault()でページ再読み込みを止め、その場で処理する
  4. 検索結果が0件のときは「該当するスキルがありません」と表示する

これで、静的だったカードに「その場で反応する」体験が加わります。


🧠 理解度チェック(一部抜粋)

  • Q. addEventListenerは何をする仕組みか? → 特定のイベント(クリック等)が発生したときに、指定した処理を実行するよう予約する
  • Q. preventDefault()が必要になる典型例は? → フォーム送信時のページ再読み込みを止め、JavaScript側で処理したいとき
  • Q. mapfilterの違いは? → mapは配列の各要素を変換した新しい配列を作る、filterは条件を満たす要素だけを残した新しい配列を作る

挫折ポイントTOP3と対処法

1. 「要素が見つからない(null)」というエラー

JavaScriptの実行タイミングが、対象のHTML要素が読み込まれる前になっていることが原因です。<script>deferをつけるか、</body>の直前にスクリプトを配置します。

2. 「thisの中身が想定と違う」問題

関数の書き方(通常のfunctionかアロー関数か)によって、thisが指すものが変わります。最初のうちはthisを多用する設計を避け、必要な値は明示的に引数で渡す書き方をおすすめします。

3. 「非同期処理の結果が想定した順番で出てこない」問題

今回はまだ扱っていませんが、次回(UIの回)で本格的に登場するfetch等の非同期処理でよく起きるつまずきです。「JavaScriptは書いた順番通りに全部が終わるとは限らない」ということを、頭の片隅に置いておいてください。

🧓 ベテランの現場コラム JavaScriptのエラーは、ブラウザの開発者ツールの「Console」タブに赤字で表示されます。「動かない」で立ち止まる前に、必ずこのタブを確認する癖をつけましょう。エラーメッセージには大抵、何行目で何が起きたかが書かれています。


この先、何を学べばいいか

DOM操作とイベントの基本が分かったら、次は 「ユーザーインターフェース(UI)」の回でSPA(1ページで完結するアプリ)と非同期通信を扱います。今回はページ内の要素を書き換えるだけでしたが、次はサーバーと通信しながらページを切り替える仕組みに挑戦します。


まとめ

  • JavaScriptは「イベントが起きたら反応する」受付係のような言語
  • addEventListenerでイベントを予約し、preventDefault()でデフォルト動作を止められる
  • DOM操作は「要素を選択→内容やスタイルを書き換える/新しく作って追加する」の組み合わせ
  • map/filterなどの配列メソッドは、ループを書く代わりの定番選択肢
  • ユーザー入力を画面に反映するときは、XSSのリスクを常に意識する

参考にした学習リソースについて

本記事は、ハーバード大学が提供する人気講座「CS50’s Web Programming with Python and JavaScript」の内容を参考にしつつ、独自の題材・独自の構成・自作のサンプルで書き下ろしたオリジナル解説記事です。CS50そのものに興味を持った方は、以下の公式サイトも覗いてみてください。

🎓 理解度テスト

学んだ内容を確認しましょう。全6問。