目次を開く(全 17 章)
01学習レベル:基礎
JavaScript の置き方
HTML から読み込むだけです。defer を付けて <head> に置くのが今の定番。これで「HTML を全部読み終えてから実行」されるので、要素が見つからないエラーを防げます。
<head>
<script src="assets/javascripts/main.js" defer></script>
</head>
書いた結果を確かめるには console.log() を使います。ブラウザで F12(Mac は ⌘ + Option + I)を押すと開発者ツールが開き、「コンソール」タブに出力されます。これがいちばん手軽なデバッグの道具です。
console.log("こんにちは、JavaScript");
console.log(1 + 2);
console.log("今日の日付:", new Date().toLocaleDateString("ja-JP"));
このページでは、コンソールの代わりに、コードの下の「実行結果」の枠へ出力しています。
main.js を defer で読み込む じゃんけんの defer と即時関数 <script> console.log()
02学習レベル:基礎
変数 — const と let
変数は、値に名前を付けて使う仕組みです。最初は名前の付いた箱のようなものと考えて構いません。
宣言には、まず const を使います。あとで値を入れ替える必要があるときだけ let を使います。
const applePrice = 100; // この買い物では、りんご 1 個 100 円
let appleCount = 2; // 買う個数はあとで変わる
appleCount = appleCount + 1; // もう 1 個買う
console.log(applePrice * appleCount); // 300
appleCount += 1; // 「appleCount = appleCount + 1」の短い書き方
console.log(applePrice * appleCount); // 400
この例では、買う個数は 2 個、3 個、4 個と変わります。一方、りんご 1 個の値段は、この買い物の計算中ずっと 100 円です。そこで、変わる個数は let、変えない値段は const で宣言します。
const にすると、後のコードでうっかり applePrice を書き換えようとしてもエラーで気付けます。コードが長くなっても、合計を計算するときには「りんご 1 個 100 円」という前提を信頼できます。単にエラーを避けるために let に変えると、その前提を守れなくなります。変える必要のない値を変えられないようにするのは「不変性」を大切にする書き方の一例です。
後で学ぶ配列やオブジェクトでは、const で宣言しても項目を追加・変更できます。const が禁止するのは、その変数名に別の配列やオブジェクトを代入し直すことです。今は「再代入しないなら const」を押さえておけば十分です。
var はブロック { } を無視して外まで漏れ出し、同じ名前で何度でも宣言できてしまいます。
const / let はブロックの中だけで有効なので、
名前の有効範囲が分かりやすくなります。名前は applePrice のように、何を表すか分かる英単語で付けます。
03学習レベル:基礎
読みやすいコード — 名前と書式
コードは、あとで読む自分にも伝わるように書きます。最初は名前を具体的にする・計算を分ける・書式を揃えるの 3 つを意識しましょう。
- 名前を具体的にする —
xやnumberより、bookPriceやbookCountなら何の値か分かります。 - 途中の値にも名前を付ける — 合計を一度に計算する代わりに、本の代金を
booksPriceに入れると、計算の順序を追えます。 - 空白と改行を揃える —
bookPrice * bookCountのように演算子の前後を空け、計算のまとまりごとに行を分けます。
const bookPrice = 500;
const bookCount = 3;
const deliveryFee = 200;
const booksPrice = bookPrice * bookCount;
const totalPrice = booksPrice + deliveryFee;
console.log(totalPrice); // 1700
booksPrice は本だけの代金、totalPrice は送料も含めた代金です。名前を付けて分けると、あとから送料の計算を変えるときも、どこを直すか分かります。
コメントは、式を読めば分かる計算の説明より、「なぜこの決まりにしたか」を残すと役立ちます。関数や条件が長くなったときの書き方は、JS 実践編でも扱います。
04学習レベル:基礎
データ型
データ型は、値の種類を表します。たとえば、商品の値段は数値、商品名は文字列です。まずは、よく使う次の種類を見てみましょう。
| 種類 | 例 | 何を表すか |
|---|---|---|
数値(number) | 1280、3.5 | 値段や個数などの数字。JavaScript では整数も小数も同じ数値型です。 |
文字列(string) | "りんご" | 名前や文章。数字に見える "1280" も、引用符で囲めば文字列です。 |
真偽値(boolean) | true、false | 「はい/いいえ」のような二択。たとえば、お店が営業中かどうか。 |
null | null | 「値がない」と意図して示す値。 |
undefined | undefined | まだ値を入れていないときなどに現れる値。 |
配列(array) | ["赤", "青"] | 複数の値を順番に並べたもの。 |
オブジェクト(object) | { name: "山田" } | 名前を付けた情報をまとめたもの。 |
数値と文字列は別の種類です。たとえば 1280 + 1 は 1281 ですが、"1280" + 1 は文字をつなげた "12801" になります。値の種類を調べるには typeof を使います。配列はオブジェクトの一種なので、typeof の結果は "object" です。
const text = "あいうえお"; // 文字列 string
const price = 1280; // 数値 number(整数も小数も同じ)
const isOpen = true; // 真偽値 boolean
const nothing = null; // 「空」だと明示した状態
let notSet; // undefined(まだ入れていない)
const list = ["赤", "青", "緑"]; // 配列 array
const user = { name: "山田", age: 30 }; // オブジェクト object
console.log(typeof text, typeof price, typeof isOpen);
console.log(typeof nothing, typeof notSet);
console.log(list.length, list[0]);
console.log(user.name, user["age"]);
typeof null が "object" になるのは JavaScript の古い不具合で、直せないまま残っています。
05学習レベル:基礎
演算子の種類と優先順位
演算子は、計算・比較・代入などに使う記号です。種類ごとに見ていきましょう。
算術演算子 — 数値を計算する
この表は、上ほど計算の優先順位が高い順です。同じ優先順位の * と / などは、通常は左から計算します。
| 記号 | 意味 | 例 |
|---|---|---|
( ) | 囲んだ部分を先に計算 | (2 + 3) * 4 → 20 |
** | 冪乗(べきじょう) | 2 ** 3 → 8 |
* / % | かける・割る・割った余り | 10 % 3 → 1 |
+ - | 足す・引く | 2 + 3 * 4 → 14 |
** を続けた場合は右からまとまります(2 ** 3 ** 2 は 2 ** (3 ** 2))。計算の順序をはっきり示したいときは ( ) を使いましょう。
インクリメント・デクリメント演算子 — 1 ずつ増減する
++ は値を 1 増やし、-- は 1 減らします。値を書き換えるので、let で宣言した変数などに使います。
| 書き方 | 変数の変化 | 式として使ったときの値 |
|---|---|---|
count++ | 1 増える | 増える前の値(後置) |
count-- | 1 減る | 減る前の値(後置) |
++count | 1 増える | 増えた後の値(前置) |
--count | 1 減る | 減った後の値(前置) |
単独で count++; と書くなら、count += 1; と同じように 1 増えます。console.log(count++); のように式の中で使うと、後置は増える前、前置は増えた後の値を渡す点に注意してください。優先順位は後置が前置より高く、どちらも ** より高いです。
比較演算子 — 値を比べる
比較の結果は true または false です。この表も優先順位の高い順です。
| 記号 | 意味 | 例 |
|---|---|---|
< > <= >= | より小さい・より大きい・以下・以上 | 5 >= 5 → true |
=== !== | 型と値が等しい・どちらかが違う | 1 === "1" → false |
等しいかどうかを調べるときは === と !== を使います。他の言語で == に慣れている人も注意してください。JavaScript の == は型を自動で変換するため、1 == "1" も true になります。この教材では == を使わず、=== を使います。
論理演算子 — 条件を組み合わせる
優先順位は !、&&、|| の順です。分かりにくいときは ( ) で条件をまとめます。
| 記号 | 意味 | 例 |
|---|---|---|
! | 否定。「はい」と「いいえ」を反転する | !true → false |
&& | かつ。両方の条件を満たす | true && false → false |
|| | または。どちらかの条件を満たす | true || false → true |
代入演算子と複合代入演算子
= は右の値を左の変数に代入します。+= などの複合代入演算子(自己代入演算子)は、今の値を使って計算し、その結果を同じ変数に代入します。どちらも let で宣言した変数など、再代入できる場所に使います。
| 記号 | 意味 | 例 |
|---|---|---|
= | 代入 | count = 3 |
**= | 冪乗して代入 | count **= 2 は count = count ** 2 |
*= /= %= | かける・割る・余りを求めて代入 | count *= 2 は count = count * 2 |
+= -= | 足す・引いて代入 | count += 1 は count = count + 1 |
**= や += の行は、対応する計算の順に並べています。代入演算子どうしの優先順位は同じです。
// 算術演算子と優先順位
console.log(3 + 4, 10 - 4, 6 * 7); // 7 6 42
console.log(10 / 3); // 3.333…(整数どうしでも小数になる)
console.log(10 % 3); // 1(余り)
console.log(2 ** 10); // 1024(冪乗)
console.log(2 + 3 * 4); // 14(かけ算が先)
console.log((2 + 3) * 4); // 20(かっこ内が先)
// + は文字列の連結にもなる。数値と混ぜると文字列になってしまう
console.log("合計" + 100, "1" + 1, "1" - 1); // 合計100 / 11 / 0
// 大小の比較
console.log(2 < 5, 5 > 5, 5 >= 5, 5 <= 4); // true false true false
// 等しい/等しくない。型まで見るこの 2 つを使う
console.log(1 === 1, 1 === "1"); // true false
console.log(1 !== 2, 1 !== "1"); // true true
console.log(1 == "1", 1 != "1"); // true false ← 型を無視するので危険
// 組み合わせる
const age = 20;
console.log(age >= 18 && age < 65); // かつ
console.log(age < 18 || age >= 65); // または
console.log(!(age >= 18)); // 否定
// 代入と複合代入(値を変えるので let を使う)
let count = 2;
count = 3;
count += 1; // count = count + 1 と同じ
console.log(count); // 4
// 前置と後置で、表示される値が違う
console.log(count++); // 4(表示してから 5 に増える)
console.log(count); // 5
console.log(--count); // 4(4 に減ってから表示する)
// 偽とみなされる値(falsy)の代表例
for (const value of [false, 0, "", null, undefined, NaN]) {
console.log(value, "→", Boolean(value));
}
// ?? は「null か undefined のときだけ」右を使う
const input = 0;
console.log(input || 10); // 10 ← 0 も偽なので置き換わってしまう
console.log(input ?? 10); // 0 ← こちらが意図どおり
// ?. は途中が無ければ undefined を返す(エラーで止まらない)
const data = { user: { name: "山田" } };
console.log(data.user?.name);
console.log(data.company?.name);
文字列に値を入れる — テンプレートリテラル
文字列を `(バッククォート)で囲むと、${...} の中に変数や計算式を書けます。
const maxCount = 5;
// + で文字列をつなぐ書き方
const messageWithPlus = maxCount + " 件まで表示できます";
// バッククォートなら、文章の中に値を入れられる
const message = `${maxCount} 件まで表示できます`;
console.log(message); // 5 件まで表示できます
console.log(messageWithPlus === message); // true(どちらも同じ文字列)
const applePrice = 100;
const appleCount = 3;
const totalMessage = `合計は ${applePrice * appleCount} 円です`;
console.log(totalMessage); // 合計は 300 円です
messageWithPlus と message は同じ文字列になります。+ で文章を分けてつなぐより、${...} で値を差し込むほうが読みやすく、値が増えても書きやすいです。
06学習レベル:基礎
選択 — 条件によって処理を分ける
プログラムは上から順に処理を進めます。これを逐次といいます。条件によって進む道を変えるのが選択、同じ処理を繰り返すのが反復です。この 3 つは、構造化プログラミングの基本です。まずは選択を見てみましょう。
if / else if / else
if は条件が true のときに処理を実行します。else if で別の条件を調べ、どれにも当てはまらなければ else に進みます。else if と else は必要なときだけ書きます。
// 条件を順に調べ、成績を決める
const score = 78;
let grade;
if (score >= 90) {
grade = "優";
} else if (score >= 70) {
grade = "良";
} else {
grade = "可";
}
console.log(grade); // 良
switch
switch は、曜日のように一つの値で処理を分けるときに使います。case に一致したところから実行し、break で抜けます。一致するものがなければ default に進みます。
const day = "sat";
let dayLabel;
switch (day) {
case "sat":
case "sun":
dayLabel = "休み";
break; // break がないと次の処理にも進む
default:
dayLabel = "平日";
}
console.log(dayLabel); // 休み
発展:値の対応表で選ぶ
選んだ飲み物から値段を取り出すだけなら、switch の代わりにオブジェクトを対応表として使えます。キー(apple など)と値段の組を並べ、drinkPrices[selectedDrink] で選んだ値を取り出します。
// 飲み物の名前と値段を対応させる
const drinkPrices = {
apple: 100,
orange: 150,
coffee: 200
};
const selectedDrink = "orange";
// 対応する値が undefined なら 0 を使う
const price = drinkPrices[selectedDrink] ?? 0;
console.log(`${selectedDrink} の値段は ${price} 円です`); // orange の値段は 150 円です
?? は左側が undefined または null のときだけ、右側の 0 を使います。たとえば値段が 0 の商品は、そのまま 0 として扱えます。値を選ぶだけなら対応表が簡潔です。フォームなどから選択値を受け取る場合は、用意したキーの一つかも確認します。選択肢ごとに異なる処理を実行する場合は if や switch を使います。
07学習レベル:基礎
反復 — 処理を繰り返す
同じ処理を繰り返すことを反復といいます。回数が決まっているか、条件で続けるか、配列の要素を順に取り出すかで書き方を選びます。
| 構文 | 使いどころ | 条件を調べるタイミング |
|---|---|---|
while | 条件を満たす間、繰り返す | 処理の前。最初から条件が偽なら 0 回 |
do...while | 少なくとも 1 回は実行したい | 処理の後。最初の 1 回は必ず実行 |
for | 回数を数えながら繰り返す | 各回の処理の前 |
for...of | 配列などの値を一つずつ取り出す | 次の値があるかを各回の前に調べる |
while と do...while では、繰り返すうちに条件が変わるようにします。変わらなければ処理が終わらないことがあります。for は「最初の値・続ける条件・毎回の更新」をまとめて書きます。
// while: 条件を先に調べる
let remaining = 3;
while (remaining > 0) {
console.log(`残り ${remaining} 回`);
remaining -= 1;
}
// do...while: 処理をしてから条件を調べる
let attemptCount = 0;
do {
attemptCount += 1;
console.log(`${attemptCount} 回目の試行`);
} while (attemptCount < 2);
// for: 回数を数える
for (let number = 1; number <= 3; number += 1) {
if (number === 2) continue; // この回だけ飛ばす
console.log(`${number} 回目`);
}
// for...of: 配列の値を順に取り出す
for (const fruit of ["りんご", "みかん"]) {
console.log(fruit);
}
break は繰り返しを終え、continue はその回の残りを飛ばして次へ進みます。配列の番号も必要な場合は、後の配列の節で entries() を紹介します。
08学習レベル:基礎
配列とよく使うメソッド
配列は「順番に並んだ値の入れ物」です。要素を順に処理するときは、前の節で学んだ for...of を基本にします。ここでは番号が必要な場合と、既存のコードで見かける forEach も確認します。
const fruits = ["りんご", "みかん", "ぶどう"];
// 1. for 文:番号(添字)を自分で進める。いちばん基本の形
for (let i = 0; i < fruits.length; i++) {
console.log(i, fruits[i]);
}
// 2. for...of:値を一つずつ取り出す
for (const fruit of fruits) {
console.log(fruit);
}
// 番号も必要なら entries() と組み合わせる
for (const [index, fruit] of fruits.entries()) {
console.log(`${index + 1} 番目:${fruit}`);
}
// 3. forEach:配列の各要素に関数を実行する書き方
fruits.forEach((fruit, index) => {
console.log(`${index + 1} 番目:${fruit}`);
});
// for と for...of は途中で抜けられる
for (const fruit of fruits) {
if (fruit === "みかん") {
break; // ここで終わり
}
console.log("見つける前:", fruit);
}
| 書き方 | 向いている場面 | 途中で抜けられる |
|---|---|---|
for | 番号を使う。逆順や 2 つ飛ばしなど、進み方を細かく決めたいとき | できる(break) |
for...of | 中身を順に見たいとき。番号は entries() で得られる。ふだんはこれ | できる(break) |
forEach | 配列の各要素に関数を実行する。番号は第 2 引数で受け取れる | できない |
forEach は配列のメソッドで、渡した関数を要素ごとに呼び出します。break や continue は使えません。関数内の return はその回の関数を終えるだけで、次の要素の処理は続きます。また、forEach 自体の返り値は undefined なので、map のように結果をつなげて使うことはできません。まずは for...of を使い、forEach は既存のコードを読めるようにしておけば十分です。
名前の付いた処理に置き換える
回すことに慣れたら、次はメソッドです。「変換するなら map」「絞り込むなら filter」のように
やりたいことが名前で分かるので、コメントが要らなくなります。まずは map / filter / find / reduce の 4 つ。
const items = [
{ name: "えんぴつ", price: 120, stock: 5 },
{ name: "ノート", price: 280, stock: 0 },
{ name: "消しゴム", price: 90, stock: 12 }
];
// map:全部を別の形に変える(個数は変わらない)
console.log(items.map((item) => item.name));
// filter:条件に合うものだけ残す
console.log(items.filter((item) => item.stock > 0).map((i) => i.name));
// find:最初の 1 つを探す(無ければ undefined)
console.log(items.find((item) => item.price < 100));
// reduce:ひとつの値にまとめる(合計・最大など)
const total = items.reduce((sum, item) => sum + item.price, 0);
console.log("合計", total);
// some / every:ひとつでも / 全部が
console.log(items.some((i) => i.stock === 0), items.every((i) => i.price > 50));
// 元の配列を壊さない並べ替え(toSorted)
const byPrice = items.toSorted((a, b) => a.price - b.price);
console.log(byPrice.map((i) => i.price), items.map((i) => i.price));
// at(-1) で最後の要素
console.log(["春", "夏", "秋", "冬"].at(-1));
// includes / join / スプレッド
console.log(["赤", "青"].includes("青"), ["赤", "青"].join(" と "));
console.log([...[1, 2], ...[3, 4]]);
sort() は元の配列を並べ替えてしまいます。toSorted() は新しい配列を返すので、元を壊しません。
09学習レベル:基礎
オブジェクト
「名前と値」の組を束ねたものです。関連するデータをひとまとめにするときに使います。
// オブジェクトは { キー: 値, キー: 値 } の形で書く
const user = { name: "山田", age: 30, city: "大阪" };
// 値を取り出す:「オブジェクト.キー」と書く
console.log(user.name);
// [ ] の中にキーを文字列で書いても、同じように取り出せる
console.log(user["city"]);
// 分割代入:必要な項目だけを、同じ名前の変数に取り出す
// const name = user.name; const city = user.city; と書くのと同じ
const { name, city } = user;
console.log(name, city);
// 名前を変えて取り出す(name を、userName という変数に入れる)
// 既定値を付ける(user に country はないので、"日本" が入る)
const { name: userName, country = "日本" } = user;
console.log(userName, country);
// 配列も同じように、順番どおりに取り出せる
const [first, second] = ["金", "銀"];
console.log(first, second);
// スプレッド構文(...):中身を広げて、新しいオブジェクトに写す
// age だけを上書きした複製を作る。元の user は変わらない
const updated = { ...user, age: 31 };
console.log(updated, user.age);
// 省略記法:{ name: name, age: age } は、{ name, age } と書ける
const age = 31;
console.log({ name, age });
// すべての項目を順に取り出す
// Object.entries() は、[キー, 値] の組を並べた配列を返す
for (const [key, value] of Object.entries(user)) {
console.log(`${key}:${value}`);
}
// キーだけの配列と、値だけの配列
console.log(Object.keys(user), Object.values(user));
配列と組み合わせる
実際のデータは、オブジェクトと配列を組み合わせた形になっていることがほとんどです。よく使うのは、次の 2 つの形です。
| 形 | 例 | 向いている場面 |
|---|---|---|
| 値が配列のオブジェクト | { spring: ["桜", …], summer: […] } | 名前(ここでは季節)から、一覧を引きたいとき |
| オブジェクトの配列 | [{ name: "ひまわり", … }, { … }] | 同じ項目を持つものを並べて、順に処理したり、絞り込んだりしたいとき |
// 値が配列のオブジェクト:季節(キー)ごとに、花の名前の配列を持つ
const seasonalFlowers = {
spring: ["桜", "チューリップ", "菜の花"],
summer: ["ひまわり", "朝顔", "ラベンダー"],
autumn: ["コスモス", "りんどう"],
winter: ["椿", "水仙", "シクラメン"]
};
console.log(seasonalFlowers.summer); // 夏の花の配列
console.log(seasonalFlowers.summer[0]); // 夏の花の 1 つ目(配列の番号は 0 から数える)
console.log(seasonalFlowers.spring.length); // 春の花の数
// キーを変数で指定するときは、. ではなく [ ] で囲む
// seasonalFlowers.season と書くと、「season」という名前のキーを探してしまう
const season = "autumn";
console.log(seasonalFlowers[season].join("・")); // join():配列をつないで、1 つの文字列にする
// オブジェクトの配列:同じ項目(name・season・color)を持つ花を並べる
const flowers = [
{ name: "桜", season: "spring", color: "桃" },
{ name: "ひまわり", season: "summer", color: "黄" },
{ name: "コスモス", season: "autumn", color: "桃" },
{ name: "椿", season: "winter", color: "赤" }
];
console.log(flowers[1].name); // 2 つ目の花(ひまわり)の名前
// for...of で、花を 1 つずつ取り出して表示する
for (const flower of flowers) {
console.log(`${flower.name}(${flower.color})`);
}
// 桃色の花の名前だけを取り出す(filter と map は、次の見出しで詳しく説明する)
const pinkFlowers = flowers.filter((flower) => flower.color === "桃"); // 桃色の花だけを残す
const pinkNames = pinkFlowers.map((flower) => flower.name); // 残った花を、名前に変える
console.log(pinkNames);
flowers[1].name は、左から「flowers の」「2 つ目の」「name」と、一段ずつ読みます。長い式も、区切って読めば迷いません。
商品の一覧をデータにする
オブジェクトの配列は、商品の一覧のように、同じ形の情報がいくつも並ぶときにも使います。花屋のアレンジメントの料金表(S・M・L の 3 つのサイズ)を、データにしてみます。
// アレンジメントの料金表。1 つの商品が、1 つのオブジェクト
const arrangements = [
{ size: "S", price: 3000 },
{ size: "M", price: 5000 },
{ size: "L", price: 8000 }
];
// for...of で、商品を 1 つずつ取り出して表示する
for (const item of arrangements) {
console.log(`${item.size} サイズ:${item.price} 円`);
}
// 配列のメソッドは、. でつないで続けて書ける(filter と map は、次の見出しで詳しく説明する)
const cheapSizes = arrangements
.filter((item) => item.price < 6000) // 6,000 円未満の商品だけを残す
.map((item) => item.size); // 残った商品を、サイズの文字に変える
console.log(cheapSizes);
// find():条件に合う、最初の 1 つを探す(ここでは M サイズの商品)
const medium = arrangements.find((item) => item.size === "M");
console.log(`${medium.size} サイズは ${medium.price} 円です`);
一度に読みにくいときは、const cheap = arrangements.filter(…); のように途中の結果に名前を付け、2 つの文に分けて書いてもかまいません。ひだまりフラワーの料金シミュレーターも、同じように料金をデータとして扱っています。
filter と map を読み解く
flowers.filter((flower) => flower.color === "桃") は、初めて見ると記号が多くて戸惑います。部品に分けて読みます。
| 部品 | 役割 |
|---|---|
filter() | 配列のメソッド。条件に合う要素だけを集めた、新しい配列を作る。元の配列は変わらない |
map() | 配列のメソッド。要素を 1 つずつ別の値に変えた、新しい配列を作る。要素の数は変わらない |
(flower) => flower.color === "桃" | アロー関数。「flower を受け取り、flower.color === "桃" の結果(true か false)を返す」小さな関数 |
アロー関数は、=> の左が受け取る値(引数)、右が返す値です。右側が 1 つの式だけなら、{ } と return を省けます。引数の名前は自由に付けられ、(f) => f.color === "桃" と書いても同じ意味です。
filter() は、配列の要素を 1 つずつこの関数に渡し、true が返ってきた要素だけを残します。map() は、関数が返した値を集めて、新しい配列にします。
次の例では、同じ「桃色の花の名前を集める」処理を、3 通りの書き方で比べます。
const flowers = [
{ name: "桜", color: "桃" },
{ name: "ひまわり", color: "黄" },
{ name: "コスモス", color: "桃" }
];
// ① for...of で書く:空の配列を用意し、条件に合う花の名前だけを push する
const pink1 = [];
for (const flower of flowers) {
if (flower.color === "桃") {
pink1.push(flower.name);
}
}
console.log(pink1);
// ② 「条件」と「変え方」を関数にして、filter と map に渡す
function isPink(flower) {
return flower.color === "桃"; // 桃色なら true、それ以外なら false を返す
}
function toName(flower) {
return flower.name; // 花のオブジェクトから、名前だけを返す
}
const pink2 = flowers.filter(isPink).map(toName);
console.log(pink2);
// ③ アロー関数で、関数をその場に書く(② と同じ意味)
const pink3 = flowers
.filter((flower) => flower.color === "桃") // 桃色の花だけを残す
.map((flower) => flower.name); // 残った花を、名前に変える
console.log(pink3);
3 つとも、結果は同じです。① は手順を自分で書く方法、② と ③ は「絞り込む」「変える」という目的を、メソッドの名前で表す方法です。③ のように、メソッドは . でつないで続けて書けます。
最初から ③ の書き方で書けなくてもかまいません。① で書いて動かし、慣れてきたら ③ と見比べてみましょう。AI が出すコードや、作例のコードには ③ の形がよく出てくるので、読めるようになっておくと役立ちます。関数の書き方は、次の「関数」の節で詳しく扱います。
表の形で確かめる
console.table() は、配列やオブジェクトを表の形で表示します。オブジェクトの配列なら、1 つのオブジェクトが 1 行になり、どの花にも同じ項目がそろっているかを一目で確かめられます。値が配列のオブジェクトなら、キーが行、配列の番号が列になります。ブラウザの開発者ツールのコンソールでも、同じように使えます。
// オブジェクトの配列を表にする:1 つの花が 1 行、項目(name・season・color)が列になる
const flowers = [
{ name: "桜", season: "spring", color: "桃" },
{ name: "ひまわり", season: "summer", color: "黄" },
{ name: "椿", season: "winter", color: "赤" }
];
console.table(flowers);
// 値が配列のオブジェクトを表にする:季節が行、配列の番号が列になる
const seasonalFlowers = {
spring: ["桜", "チューリップ", "菜の花"],
summer: ["ひまわり", "朝顔"]
};
console.table(seasonalFlowers);
(index) の列は、配列の番号か、オブジェクトのキーです。console.table(flowers, ["name"]) のように列の名前を渡すと、その列だけを表示します。
形を作り替える
同じデータでも、使い方に合わせて形を変えると、扱いやすくなります。花の図鑑(オブジェクトの配列)から、季節ごとの一覧(値が配列のオブジェクト)を作り、今月のおすすめの花を表示してみます。
// 花の図鑑:花ごとに、名前と季節を持つ
const flowers = [
{ name: "桜", season: "spring" },
{ name: "チューリップ", season: "spring" },
{ name: "ひまわり", season: "summer" },
{ name: "朝顔", season: "summer" },
{ name: "コスモス", season: "autumn" },
{ name: "椿", season: "winter" },
{ name: "水仙", season: "winter" }
];
// 季節ごとの一覧を入れる、空のオブジェクト
const bySeason = {};
for (const flower of flowers) {
// その季節の配列がまだなければ、空の配列を用意する
// (まだないキーを読むと undefined になり、!undefined は true になる)
if (!bySeason[flower.season]) {
bySeason[flower.season] = [];
}
// その季節の配列に、花の名前を足す
bySeason[flower.season].push(flower.name);
}
console.log(bySeason);
// 月から季節を引く表。1 月から 12 月の順に、12 個並べている
const seasonOfMonth = [
"winter", "winter", "spring", "spring", "spring", "summer",
"summer", "summer", "autumn", "autumn", "autumn", "winter"
];
// new Date().getMonth() は、今月の番号。1 月を 0、12 月を 11 と数えるので、
// 配列の番号として、そのまま使える
const now = seasonOfMonth[new Date().getMonth()];
console.log(`今月のおすすめ:${bySeason[now].join("・")}`);
季節を決める部分も、if を重ねる代わりに、12 か月分の配列から引いています。条件分岐を、データで置き換える書き方です。
小さなクイズを作る
オブジェクトの配列の中に、さらに配列を入れることもできます。問題文・選択肢・正解の番号を 1 つのオブジェクトにまとめ、問題の数だけ並べます。
// クイズの問題を並べた配列。1 問が 1 つのオブジェクト
// question:問題文
// choices :選択肢の配列
// answer :正解の選択肢の番号(0 から数える)
const quiz = [
{ question: "春に咲く花は?", choices: ["コスモス", "りんどう", "桜"], answer: 2 },
{ question: "夏に咲く花は?", choices: ["椿", "ひまわり", "水仙"], answer: 1 },
{ question: "秋に咲く花は?", choices: ["コスモス", "朝顔", "シクラメン"], answer: 0 },
{ question: "冬に咲く花は?", choices: ["チューリップ", "ラベンダー", "水仙"], answer: 2 }
];
// 解答:選んだ選択肢の番号を、問題の順に並べたもの。書き換えて試せる
const myAnswers = [2, 1, 1, 2];
let score = 0; // 正解の数。あとで増やすので const ではなく let
// entries() で、問題の番号(index)と問題(item)を一緒に取り出す
for (const [index, item] of quiz.entries()) {
const mine = item.choices[myAnswers[index]]; // 選んだ選択肢の文字
const correct = item.choices[item.answer]; // 正解の選択肢の文字
// index は 0 から数えるので、+ 1 して「第 1 問」から表示する
if (myAnswers[index] === item.answer) {
score += 1;
console.log(`第 ${index + 1} 問 ○ ${item.question} ${mine}`);
} else {
console.log(`第 ${index + 1} 問 × ${item.question} ${mine}(正解は ${correct})`);
}
}
console.log(`${quiz.length} 問中 ${score} 問正解`);
item.choices[item.answer] は、「その問題の選択肢のうち、正解の番号のもの」です。問題を増やすときは、配列にオブジェクトを 1 つ加えるだけで、処理は書き換えずに済みます。
5 問目を加えて、myAnswers にも答えを 1 つ足してみましょう。後の「DOM」の節で学ぶ方法を使うと、選択肢をボタンとして並べ、押して答えるクイズにもできます。
じゃんけんのルールのオブジェクト 分割代入 スプレッド構文 Object.entries() filter() map() アロー関数 console.table()
10学習レベル:基礎
関数
関数は、処理をまとめて必要なときに呼び出せるようにしたものです。まず基本の書き方を見てから、関数を渡したり、値を覚えたりする使い方へ進みます。
基本形 — function とアロー関数
name は関数が受け取る値の名前です。greet("山田") の "山田" が渡す値(引数)、return で呼び出し元に返す値が戻り値です。function で宣言する方法と、=> を使って関数を変数に入れる方法があります。
// function を使う関数宣言
function greet(name) {
return `${name}さん、こんにちは`;
}
// アロー関数の基本形
const addOne = (number) => {
return number + 1;
};
// 式が一つなら { } と return を省略できる。同じ処理になる
const addOneShort = (number) => number + 1;
// 処理を複数書くなら { } と return を使う
const rectangleArea = (width, height) => {
const size = width * height;
return size;
};
console.log(greet("山田")); // 山田さん、こんにちは
console.log(addOne(21), addOneShort(21)); // 22 22
console.log(rectangleArea(3, 4)); // 12
// rate を省略した場合は 0.1 を使う(既定値)
const addTax = (price, rate = 0.1) => Math.round(price * (1 + rate));
console.log(addTax(1000)); // 1100
console.log(addTax(1000, 0.08)); // 1080
どちらで書いても動きますが、役割で使い分けると、読む人が迷いません。
| 使う場面 | 書き方 | 例 |
|---|---|---|
| 名前を付けて使う関数 | function 宣言 | function greet(name) { … } |
| ほかの関数に渡す処理(コールバック) | アロー関数 | button.addEventListener("click", () => { … }) |
| オブジェクトやクラスの中の処理 | メソッド記法 | { greet(name) { … } } |
function greet() と書けば、関数を作っていることが一目で分かります。const greet = () => { … } は、変数の宣言にも見えます。
function 宣言は定義より前でも呼び出せます(巻き上げ)。const に入れたアロー関数は、その行より前では使えません。
アロー関数は、その場で短い処理を渡すときに向いています。
両者は this の扱いも異なるため、オブジェクト自身を this で参照するメソッドには、メソッド記法を使います。
this とメソッドの詳しい使い方は、実践編のクラスで扱います。ここでは「名前付きは function、渡す処理はアロー関数」と理解すれば十分です。
レスト引数とスプレッド構文 — 個数をまとめる・広げる
... は書く場所で役割が変わります。関数を定義するときの ...numbers は「レスト引数」で、残りの引数を一つの配列にまとめます。関数を呼ぶときの ...itemPrices は「スプレッド構文」で、配列の値を一つずつ引数として渡します。個数が決まっていない値を受け取ったり、手元の配列をそのまま渡したりするときに便利です。
function sum(...numbers) {
let total = 0;
for (const number of numbers) {
total += number;
}
return total;
}
console.log(sum(100, 200)); // 300
const itemPrices = [100, 200, 300];
console.log(sum(...itemPrices)); // 600
コールバック — 渡した先で呼ばれる関数
関数は、数値や文字列と同じように、ほかの関数へ渡せます。渡した先で呼び出される関数をコールバックといいます。下の例では sayHello を渡し、repeatTwice の中で呼び出します。繰り返し方はそのままで、渡す処理だけを入れ替えられます。
function repeatTwice(action) {
action();
action();
}
function sayHello() {
console.log("こんにちは");
}
repeatTwice(sayHello); // 「こんにちは」が 2 回出る
repeatTwice(sayHello) は関数そのものを渡します。sayHello() と書くと、渡す前にその場で実行してしまいます。
map() — 配列の各値を変換する
map() は配列に備わった機能です。配列の値を一つずつコールバックへ渡し、その戻り値を並べた新しい配列を作ります。元の配列は変えずに、同じ変換をすべての値に適用したいときに便利です。
function addTaxToPrice(price) {
return Math.round(price * 1.1);
}
const prices = [100, 200, 300];
const pricesWithTax = prices.map(addTaxToPrice);
console.log(pricesWithTax); // [110, 220, 330]
console.log(prices); // [100, 200, 300] のまま
map(addTaxToPrice) では、map() が価格を一つずつ addTaxToPrice() に渡します。戻ってきた税込み価格が pricesWithTax に並びます。
クロージャ — 前に作った値を覚えている関数
関数の中で別の関数を作ると、内側の関数は外側の変数を使い続けられます。この仕組みをクロージャといいます。下の count は makeCounter() の実行後も内側の関数に残ります。カウンターごとに値を分けて持てるので、全体で共有する変数を増やさずに済みます。
function makeCounter() {
// 呼び出すたびに新しい count を作るので、カウンター同士が影響しない。
let count = 0;
return () => {
count += 1;
return count;
};
}
const firstCounter = makeCounter();
const secondCounter = makeCounter();
console.log(firstCounter(), firstCounter()); // 1 2
console.log(secondCounter()); // 1
同じ形のデータと処理を複数まとめて使う方法は、実践編のクラスで学びます。
11学習レベル:基礎
DOM 操作 — HTML を読み書きする
ブラウザは HTML を読み込むと、要素をたどれる木構造(DOM)に変換します。 JavaScript はこの木を探して・読んで・書き換えることでページを動かします。
下のデモは、この HTML に対して動いています。
<h3 id="title">見出し</h3>
<p class="message">ここが書き換わります</p>
<ul id="list"></ul>
<button id="paint" type="button">色を変える</button>
見出し
// 1. 探す(CSS セレクタがそのまま使える)
const title = document.querySelector("#title");
const message = document.querySelector(".message");
const list = document.querySelector("#list");
// 2. 書き換える
title.textContent = "JavaScript で書き換えた見出し";
message.textContent = `いまは ${new Date().toLocaleTimeString("ja-JP")} です`;
// 3. 作って足す
const fruits = ["りんご", "みかん", "ぶどう"];
for (const fruit of fruits) {
const li = document.createElement("li");
li.textContent = fruit;
list.append(li);
}
// 4. 見た目を変える
title.classList.add("is-active");
title.style.color = "#2f80b8"; // 直接スタイルを当てることもできる
// 5. まとめて処理する
for (const li of document.querySelectorAll("#list li")) {
li.style.fontWeight = "700";
}
// ボタンの動作は次の章で
document.querySelector("#paint").addEventListener("click", () => {
message.style.backgroundColor = "#eaf2f8";
});
「色を変える」を押すと、実際に背景色が変わります。
- querySelector()
- 条件に合う最初の 1 つ。無ければ
null。 - querySelectorAll()
- 合うもの全部。
for...ofで回せます。 - textContent
- 文字を読み書きする。安全なのでまずこちら。
- innerHTML
- HTML として解釈する。外部から来た文字を入れると危険(制作の心得参照)。
- createElement / append
- 要素を作って、子として加える。
- classList
add/remove/toggle/contains。見た目の変更は CSS のクラス切り替えで。- closest()
- 自分から親をたどって、条件に合う祖先を探す。イベント処理で多用します。
data-* 属性とは
data-* は、HTML の要素に自分で名前を付けた情報を持たせるための属性です。* は名前を表す記号で、実際には data-action="refresh" や data-ui="item-card" のように書きます。ブラウザがこれらに特別な動作を付けるわけではありません。JavaScript が「どのボタンか」を見分けたり、CSS が状態に合わせて見た目を変えたりするときの目印になります。
JavaScript では、要素の dataset から値を読み書きできます。data-action は dataset.action、data-max-count は dataset.maxCount に対応します。HTML の属性名にあるハイフンを、JavaScript 側では次の単語を大文字にして表します。
data-* を目印に要素を探す
getElementById() も、ページに一つだけの要素には有効です。ただ、同じ構造のカードが複数ある画面では、各子要素に固有の ID を振るより、カードを起点に data-ui を探すほうが再利用しやすくなります。CSS 用のクラス名を変えても JavaScript の参照が壊れません。
<section data-ui="item-card">
<span data-ui="item-count">0 件</span>
<button type="button" data-action="refresh" data-max-count="5">更新</button>
</section>
<script>
const card = document.querySelector('[data-ui="item-card"]');
const itemCount = card.querySelector('[data-ui="item-count"]');
const refreshButton = card.querySelector('[data-action="refresh"]');
const action = refreshButton.dataset.action; // "refresh" を読む
const maxCount = Number(refreshButton.dataset.maxCount); // "5" を数値の 5 に変える
itemCount.textContent = `${maxCount} 件まで表示できます`;
card.dataset.state = "ready"; // data-state="ready" を設定する
</script>
querySelector('[data-action="refresh"]') は、属性の値が refresh の要素を探します。dataset.action はその値を読み、dataset.state = "ready" は HTML 側に属性を追加・更新します。data-* の値は文字列なので、数値として計算する場合は Number() で変換します。存在しない属性を dataset で読むと undefined です。id はラベルの for やページ内リンクなど、本来の用途でも使い続けます。
クラスを付け替えて表示する じゃんけんの部品を data-* で探す querySelector() querySelectorAll() textContent classList dataset
12学習レベル:基礎
イベント — 操作に反応する
「クリックされたら」「入力されたら」を addEventListener() で登録します。
HTML に onclick="…" と書く方法もありますが、
処理は JavaScript 側にまとめるのが今の作法です。
こんにちは、ゲストさん
// クリック
const counter = document.querySelector("[data-count]");
let count = 0;
counter.addEventListener("click", () => {
count += 1;
counter.textContent = `押した回数:${count}`;
});
// 入力のたびに反応する
const who = document.querySelector("#who");
const hello = document.querySelector(".hello");
who.addEventListener("input", (event) => {
const name = event.target.value.trim();
hello.textContent = `こんにちは、${name || "ゲスト"}さん`;
});
// イベント委譲:親で 1 つだけ受けて、どれが押されたかを調べる
// ボタンが増えても登録し直さなくてよい
document.querySelector(".menu").addEventListener("click", (event) => {
const button = event.target.closest("button");
if (!button) return;
hello.style.color = button.dataset.color;
});
event.target… 実際に操作された要素。event.currentTargetは登録した側の要素です。event.preventDefault()… 既定の動作(リンクの移動、フォーム送信)を止めます。- よく使うイベント:
clickinputchangesubmitkeydownpointerdownscroll。 - スクロールなど大量に発火するイベントは、中で重い処理をしないこと。必要なら
requestAnimationFrameで間引きます。
入力のたびに計算し直す メニューを開閉する じゃんけんのボタンで 1 回勝負する addEventListener() event.target preventDefault()
13学習レベル:実践
非同期処理 — 待つ処理の書き方
通信やタイマーは「すぐには終わらない処理」です。
JavaScript は待っている間も止まらずに次へ進むので、
終わったら何をするかを書いておく必要があります。それが Promise と async / await です。
// 「あとで終わる処理」を作る
const wait = (ms, value) => new Promise((resolve) => setTimeout(() => resolve(value), ms));
console.log("1. ここが先に動く");
// async を付けた関数の中では await で「終わるまで待つ」と書ける
async function main() {
const first = await wait(10, "お茶");
console.log("3. 届いた:", first);
// 順番に待つ必要がないものは、まとめて待つほうが速い
const [a, b] = await Promise.all([wait(10, "パン"), wait(10, "牛乳")]);
console.log("4. まとめて:", a, b);
// 失敗するかもしれない処理は try / catch で囲む
try {
await Promise.reject(new Error("通信に失敗しました"));
} catch (error) {
console.log("5. 捕まえた:", error.message);
}
}
main();
console.log("2. 待たずにここまで進む");
出力の順番に注目してください。1 → 2 → 3 → 4 → 5 の順で出ます。
async function loadUsers() {
try {
const response = await fetch("/api/users.json");
// fetch は 404 でも例外にならない。自分で確かめる
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
const users = await response.json();
return users;
} catch (error) {
console.error("読み込みに失敗しました", error);
return [];
}
}
ファイルをダブルクリックして開いた状態(file://)では、セキュリティ上の制限で fetch や ES モジュールが動きません。試すときは、エディタの「ローカルサーバーで開く」機能を使うか、
ruby -run -e httpd . -p 8000 のような簡易サーバーを立ててください。
通信の流れは実践編のブラウザとサーバー、コードを役割ごとにファイルへ分ける方法は実践編のモジュールで学びます。
じゃんけんのファイルの読み込み じゃんけんの確認を await で待つ Promise async function await fetch()
失敗に備える — try / catch
通信は、電波が届かない、サーバーが止まっているなどの理由で失敗することがあります。処理が失敗すると、JavaScript は例外(エラー)を投げ、そのままではそこで処理が止まります。try { … } catch (error) { … } で囲んでおくと、try の中で例外が投げられたとき、catch に移って続きの処理を書けます。
// 文字を数値に直す。数値にならなければ、自分で例外を投げる
function parsePrice(text) {
const price = Number(text);
if (Number.isNaN(price)) {
throw new Error(`「${text}」は数値ではありません`);
}
return price;
}
try {
console.log(parsePrice("1280")); // 1280
console.log(parsePrice("千円")); // ここで例外が投げられ、catch へ移る
console.log("この行は実行されない");
} catch (error) {
// error.message に、投げたときの文が入っている
console.log(`読み取れませんでした:${error.message}`);
} finally {
console.log("finally は、成功しても失敗しても最後に実行される");
}
console.log("catch で受け止めたので、ここから先も動く");
try の中で例外が投げられると、残りの行は飛ばされ、catch に移ります。catch で受け止めたので、最後の行まで処理が続きます。
throwで自分から投げる …throw new Error("理由")と書くと、その場で例外を投げられます。上のparsePrice()のように、「この値では続けられない」ことを呼び出し元に知らせるときに使います。awaitの失敗も受け止められる …async関数の中では、awaitで待った処理の失敗も、同じtry/catchで受け止められます。上の「サーバーからデータを取る」例がこの形です。- 失敗したら何をするかを書く …
catchの中では、利用者に理由を知らせる、空のデータで続けるなど、次にどうするかを書きます。何も書かずに例外を受け止めるだけにすると、失敗したことに誰も気づけません。 - 囲むのは、失敗しうるところだけ … 通信、
JSON.parse()、保存など、外からの事情で失敗する処理を囲みます。自分のコードの書き間違いは、tryで隠さずに直します。
14学習レベル:実践
最近入った便利な機能
JavaScript は毎年更新されています。ここ数年で入って、 必要になったときに調べたいものをいくつか挙げます。この節は、初回は飛ばしてもかまいません。
const prices = [300, 100, 200];
// toSorted() は並べ替えた新しい配列を返す。
const sortedPrices = prices.toSorted((left, right) => left - right);
console.log(sortedPrices); // [100, 200, 300]
console.log(prices); // [300, 100, 200] のまま
// at(-1) で配列の最後の値を読める。
console.log(prices.at(-1)); // 200
言語仕様は毎年 6 月に更新され、ブラウザへの搭載はそれとは別のペースで進みます。 使う前に MDN の「ブラウザーの互換性」表か、Can I use で対応状況を確認してください。 ほかにも新しい機能がありますが、最初から一覧を覚える必要はありません。使いたい操作が出てきたら調べましょう。
15学習レベル:基礎
動かないときの調べ方
エラーは、どこで何が起きたかを知らせる、ブラウザからの手がかりです。 まずコンソールを開きます。
| よく出るエラー | たいていの原因 |
|---|---|
Cannot read properties of null | 要素が見つかっていない。セレクタの綴り違い、または defer の付け忘れ |
X is not defined | 変数名の打ち間違い、宣言し忘れ、スコープの外から使っている |
X is not a function | メソッド名の間違い(querySelectorAll を querySelector と書いた等) |
Unexpected token | 括弧や引用符の閉じ忘れ。エラーのすぐ上の行を疑う |
| 何も起きない | そもそも関数が呼ばれていない。console.log("ここ通った") を入れて確認 |
- コンソールを開く
赤い文字を読む。ファイル名と行番号が書いてあります。
- console.log を挟む
「どこまで動いたか」「変数に何が入っているか」を実際に見ます。
- 要素タブで DOM を見る
思ったクラスが付いているか、CSS のどの行が効いているかが分かります。
- 小さく切り分ける
怪しい部分だけを取り出して、単独で動かしてみます。
- それでも分からなければ検索
エラーメッセージをそのまま貼って検索。MDN の解説が出てくれば当たりです。
16学習レベル:実践
モダンな Web 制作で知っておいてほしいこと
文法とは別に、作り方の姿勢の話です。最初にこれを知っておくと、あとで作り直す回数がかなり減ります。
-
HTML → CSS → JavaScript の順で足す(段階的強化)
まず HTML だけで内容が読める状態を作り、CSS で整え、最後に JavaScript で便利にします。 JS が読み込めなくてもページが使えなくなることのない構造になり、表示も速くなります。
<details>や:has()で済むことに JS を使わない、という判断もここに含まれます。 -
デバイスの幅を決め打ちしない
「iPhone は 390px だから」と個別対応を始めると終わりません。 内容が崩れる幅で切り替えます。
clamp()やauto-fillを使えば、そもそも切り替え自体が減ります。 -
アクセシビリティは最初から考える
正しいタグ、ラベル、代替テキスト、キーボード操作、コントラスト。最初から確認しておくと、作り終わってから直す手間を減らせます。 マウスを外して Tab キーだけで操作してみるのが、いちばん手軽な自己点検です。
-
画像の大きさを確認する
大きな画像は表示を遅くすることがあります。用途に合う大きさと形式を選び、
width/heightを書き、画面外の画像には必要に応じてloading="lazy"を使います。 -
innerHTML に外から来た文字を入れない
利用者の入力や URL の値をそのまま
innerHTMLに入れると、スクリプトを埋め込まれる恐れがあります(XSS)。 文字を入れるだけなら必ずtextContent。外部サイトへのリンクにはrel="noopener noreferrer"を付けます。 -
フレームワークは急がなくてよい
React や Vue は「状態が複雑なアプリ」のための道具です。数ページのサイトなら素の HTML/CSS/JS のほうが速くて壊れにくい。 土台が分かっていないと、フレームワークの不具合は直せません。
-
ファイル構成と名前を決めておく
assets/stylesheets/assets/javascripts/assets/images/のように場所を決め、ファイル名は半角小文字とハイフンで。迷う時間が消え、他人(半年後の自分を含む)が読めるようになります。 -
バージョン管理を最初から使う
Git を入れて、区切りごとに記録(コミット)します。「昨日は動いていたのに」から復帰できるようになるだけで、挑戦できる幅が変わります。 GitHub に置けば、そのまま公開(GitHub Pages)もできます。
-
ブラウザの開発者ツールをいつも開いておく
要素タブで DOM と CSS、コンソールでエラー、ネットワークで読み込み、 Lighthouse で速度とアクセシビリティの点検。 説明を読んだら実際のページでも試してみましょう。
-
情報源を絞る
仕様と使い方は MDN Web Docs、対応状況は Can I use。古い記事は「その時点の正解」でしかありません。
floatで段組み、var、jQuery 前提の解説を見かけたら、まず年代を確認してください。
全部を覚えてから作り始める必要はありません。 小さくても、動くものを最後まで作るほうが、確実に身につきます。分からないことはそのつど調べればよく、そのために MDN があります。
17
次は JavaScript 実践編へ
HTML で構造を、CSS で見た目を、JavaScript で動きを作れるようになりました。次は、サイトやアプリを育てるためのコードの整理、保存、オフライン対応へ進みます。
ボタンと数字をページに置き、押すたびに数字が 1 増えるようにしてみましょう。次に、数字が 10 になったらボタンを押せなくします。変数・選択・DOM・イベントを一度に使えます。