JavaScript

ブラウザの中で動く、いちばん近い言語

いま85本。実行して確かめたものだけを置いています。

01学ぶ

順番に積み上げる

✓array/basics

配列の基本 — 作る・取り出す・数える

配列は値を順番に並べて1つの名前で扱う入れ物です。作り方、番号での取り出し方、長さの数え方、範囲の外を読んだときに何が起きるかまでを、実行しながら確かめます。

✓array/loop

配列を繰り返す — for / for...of / forEach

配列の要素を1つずつ処理する3つの書き方を、違いが分かる形で比べます。途中で抜けられるか、添字が使えるか、非同期で待てるか。選ぶ基準まで実行して確かめます。

✓array/transform

配列を変換する・絞り込む — map と filter

ループで書いていた「新しい配列を作る」処理を map と filter に置き換えます。繋げて書く方法、元の配列が変わらないこと、途中で空になっても落ちない理由…

✓function/basics

関数の基本 — 作る・呼ぶ・返す

関数の3つの書き方と、それぞれで変わること。戻り値を書き忘れたときに何が返るか、アロー関数でオブジェクトを返すときの落とし穴までを、実行しながら確かめます。

✓function/higher-order

関数を値として扱う — 渡す・返す・包む

関数は値なので、変数に入れ、配列に並べ、引数として渡せます。map に渡している形の正体、関数を返す関数、既存の関数を包んで機能を足す形までを実行して確かめます…

✓function/scope

スコープと閉包 — 変数はどこから見えるか

変数が見える範囲と、関数が「作られた場所の変数を覚えている」という性質を扱います。ループの中で作った関数が全部同じ値になる有名な罠と、その原因までを実行して確か…

✓object/basics

オブジェクトの基本 — 作る・読む・書き換える

オブジェクトは名前を付けて値をまとめる入れ物です。作り方、ドットと角括弧の使い分け、無い鍵を読んだときの結果、あるかどうかの調べ方、同じものを指すという性質まで…

✓object/iterate

オブジェクトを回す・変換する

オブジェクトには map も filter もありません。entries() で配列にしてから配列のメソッドを使い、 fromEntries() で戻します。鍵…

✓object/nested

入れ子のオブジェクトを安全に扱う

深いところを辿ると途中で落ちます。オプショナルチェーンで落ちないようにする方法、分割代入で必要な値だけ取り出す書き方、既定値の付け方と ?? と || の違いを…

✓string/basics

文字列の基本 — 作る・つなぐ・数える

文字列の作り方、テンプレートリテラルでの組み立て、length での数え方、そして「一度作った文字列は書き換えられない」という性質までを、実行しながら確かめます…

✓string/search

文字列を探す・分ける・置き換える

includes() と indexOf() の使い分け、-1 が返る理由と 0 が falsy になる落とし穴、大文字小文字を無視した検索、split() と…

✓string/slice

文字列を切り出す・整える — slice と trim

slice() で必要な部分だけ取り出す方法と、substring() との違いを実行して比べます。 trim() で落とせる空白と落とせない空白、padSta…

✓string/unicode

文字を正しく数える — 絵文字と結合文字

length が見た目の文字数と合わない理由を、サロゲートペアと結合文字から説明します。スプレッド構文と Intl.Segmenter による数え方の違い、正規…

02逆引き

やりたいことから引く

✓array/chunk

配列を決まった数ずつに分ける

slice() を繰り返して塊にします。端数の扱い、空配列のとき、要素数より大きい数を渡したとき、そして 0 を渡すと止まらなくなる理由まで、実行して確かめます…

✓array/compare

2つの配列を比べる — 同じか、共通は何か

配列同士を === で比べても中身は見ません。中身が同じか調べる方法、順序を無視して比べる方法、共通・差分の求め方、オブジェクトの配列で気をつけることまで実行し…

✓array/flatten

入れ子の配列を平らにする

入れ子になった配列を1段階だけ、または全部平らにする方法をまとめます。flat() の深さ指定、 flatMap() で変換と平坦化を同時にやる書き方、穴が消え…

✓array/group

配列をキーごとにまとめる(グループ化)

Object.groupBy が使えるならそれが最短です。使えない環境向けの reduce での書き方、キーが数値や undefined になる罠、件数だけ数え…

✓array/insert-remove

配列の途中に入れる・途中から消す

splice() は元の配列を書き換え、消したものを返します。引数の意味、挿入と置き換え、ループの中で消すと1つ飛ばす理由、元を壊さない toSpliced()…

✓array/max-min

配列の最大値・最小値を求める

Math.max() にスプレッドで渡すのがいちばん短い書き方です。空配列で -Infinity になること、 null が 0 に化けること、件数が多いと落ち…

✓array/partition

配列を条件で2つに分ける

条件に合うものと合わないものを、1回のループで2つの配列に分けます。 filter() を2回書く方法との違い、条件の否定を書き間違えて件数が合わなくなる罠まで…

✓array/remove-duplicates

配列から重複を取り除く

配列の重複を消す最短の書き方は [...new Set(arr)] です。順序は保たれます。オブジェクトの配列では消えない理由と、その場合の書き方も載せています…

✓array/search

オブジェクトの配列から探す

1件なら find()、複数なら filter()、あるかどうかなら some()。大文字小文字や全角半角で見つからない理由、複数の項目をまたいで探す形、何度も…

✓array/sort-numbers

配列を数値の大きさで並び替える

sort() は既定で文字列として比べるため、数値を渡すと [1, 10, 2] のように並びます。比較関数の書き方、元の配列を壊さない方法、日本語やオブジェク…

✓array/sum

配列の合計を出す

合計は reduce に初期値 0 を渡すのが基本です。小数がずれる理由、空配列で例外になる条件、オブジェクトの配列の合計、大きすぎる数の扱いまで、実行して確か…

✓async/parallel

複数の非同期処理を同時に走らせる

await をループの中で書くと1つずつ順番に待ってしまいます。Promise.all で同時に走らせる書き方、1つ失敗したときの扱い、forEach で待てな…

✓async/retry

失敗したら再試行する

一時的な失敗だけをやり直します。回数で打ち切る書き方、待ち時間を伸ばす理由、やり直してはいけない失敗の見分け方、最後の失敗を握りつぶさない形までを実行して確かめ…

✓async/timeout

非同期処理に制限時間を付ける

Promise.race() で時間切れにできますが、遅いほうは裏で走り続けます。本当に止めるには AbortSignal が要ります。両方の書き方と、どちらを…

✓date/diff

2つの日付の差を日数で出す

引き算するとミリ秒が返ります。86400000 で割れば日数ですが、時刻が混ざると1日ずれます。日付だけに揃えてから引く形、負の差、月をまたぐ場合、年齢の数え方…

✓object/empty-check

空かどうかを調べる — 配列・オブジェクト・文字列

空の配列も空のオブジェクトも真なので、if (value) では判定できません。それぞれの正しい調べ方、null と空を分けるべき理由、1つの関数にまとめる形ま…

✓object/merge

オブジェクトを結合する

結合はスプレッド構文が最短です。ただしコピーされるのは1階層目だけで、入れ子は元と共有されます。undefined で上書きされる罠と、深く複製する方法までまと…

✓object/pick

オブジェクトから必要な鍵だけ取り出す・除く

entries() で配列にして絞り、fromEntries() で戻します。分割代入の残余で除く短い書き方、無い鍵を渡したとき、入れ子が共有されたままになる点…

✓string/format-date

日付を「2026-09-08」や「2026年9月8日」に整形する

日付を決まった形の文字列にする方法をまとめます。Intl.DateTimeFormat と toISOString の使い分け、時間帯で結果が変わる落とし穴、月…

✓string/to-number

文字列を数値に変換する

Number() と parseInt() と単項プラスは、失敗したときの振る舞いが違います。空文字・全角・単位つき・カンマ区切りで何が起きるかを実行して確かめ…

✓string/truncate

文字列を決まった文字数で切り詰める

長い文字列を指定した文字数で切って「…」を付ける方法をまとめます。slice() で絵文字が壊れる理由、スプレッド構文で足りない場面、Intl.Segmente…

✓url/query

URL のクエリ文字列を読む・組み立てる

自分で split() しないでください。URLSearchParams が符号化も復号も同じ値の複数指定も扱います。必ず文字列で返ること、空とキー無しの見分け…

03調べる

用語と仕様

✓array/every-some

every() と some() — 全部か、1つでもあるか

every() は全部が満たすか、some() は1つでも満たすかを true / false で返します。空配列で答えが逆になること、途中で止まること、inc…

✓array/filter

Array.prototype.filter()

filter() は配列の各要素を関数に通し、true になった要素だけを集めた新しい配列を返します。元の配列は変わりません。要素数は減ることがあります。

✓array/find

Array.prototype.find()

find() は条件に合う最初の要素を返します。見つからなければ undefined です。途中で止まること、空振りの扱い、findIndex や filter…

✓array/from

配列を作る — Array.from() / Array.of() / new Array()

new Array(3) が作るのは「穴が3つ」で、map() が動きません。Array.from() との違い、 fill() で同じオブジェクトが共有される…

✓array/includes

Array.prototype.includes() と some() / every()

値が入っているかを調べる includes、条件で調べる some と every の違いをまとめます。 NaN が見つかる理由、型が違うと一致しない話、空配列…

✓array/join

join() — 配列を1本の文字列にする

join() は要素を区切り文字で繋ぎます。null と undefined が空文字になること、区切りを省くとカンマになること、入れ子の配列が平らに見えること…

✓array/map

Array.prototype.map()

map() は配列の各要素を関数に通し、その戻り値を集めた新しい配列を返します。元の配列は変わりません。要素数も変わりません。

✓array/push

push() / pop() / shift() / unshift()

4つとも元の配列を書き換えます。それぞれの戻り値、空配列で何が返るか、配列を丸ごと足すと入れ子になる理由、元を変えずに同じことをする書き方までを実行して確かめま…

✓array/reduce

Array.prototype.reduce()

reduce() は配列を1つの値にまとめます。初期値を省いたときの落とし穴、空配列で例外になる条件、合計・グループ化の書き方、いつ使わないほうがよいかまでまと…

✓array/slice

Array.prototype.slice() と splice()

名前が似ている slice() と splice() は、まったく別のものです。取り出すだけか元を書き換えるか、引数の意味の違い、負の数の扱い、浅いコピーになる…

✓array/sort

Array.prototype.sort() と toSorted()

sort() は比較関数を渡さないと文字列として並べます。比較関数が返すべき値、真偽値を返すと並ばない理由、undefined と穴の位置、安定ソートの保証まで…

✓class/class

class — 作る・継承する・隠す

コンストラクタ、メソッド、getter、静的メンバ、継承、# で始まる非公開フィールドまでを扱います。 new を忘れると落ちる理由、JSON にすると非公開が…

✓collection/map-set

Map と Set

Map はどんな値でも鍵にでき、Set は重複を持ちません。オブジェクトや配列と何が違うのか、同じ値とみなす基準、JSON にできない理由、集合の演算までを実行…

✓date/date

Date — 作る・比べる・差を出す

Date が持っているのは 1970 年からのミリ秒だけです。比較が動く理由、差が引き算で出る理由、月を足すと 1/31 が 3/3 になる理由、壊れた日付の見…

✓error/error

Error と try / catch / finally / throw

Error が持っているもの、throw できるもの、finally が必ず動くこと、JSON にすると空になる理由、 cause で原因を繋ぐ書き方、独自のエ…

✓function/parameters

関数の引数 — 既定値・可変長・分割代入

既定値が働くのは undefined のときだけです。null では働きません。可変長引数の受け取り方、オブジェクトで受けて名前を付ける書き方、length が…

✓iterator/iterable

反復可能とイテレータ — for...of で回せるものの正体

for...of とスプレッドが使えるかどうかは Symbol.iterator を持つかで決まります。自分で作る方法、ジェネレータ、1度きりしか回せないこと、…

✓json/parse

JSON.parse() と JSON.stringify()

JSON との変換で何が消え、何が形を変えるのかをまとめます。undefined や Map が黙って落ちる理由、循環参照で例外になる条件、reviver と …

✓number/rounding

数値を丸める — Math.round / floor / ceil / trunc と toFixed

4つの丸め方の違い、負の数で結果が分かれる理由、toFixed が文字列を返すこと、そして 1.005 が 1.00 になる理由と、その回避策も効かない場面まで…

✓object/assign

Object.assign() と Object.freeze()

Object.assign() は第1引数を書き換えて返します。後ろが勝つこと、複製が1段しか効かないこと、 getter が値に変わること、freeze() …

✓object/keys

Object.keys() / values() / entries()

オブジェクトのキー・値・組を配列で取り出します。継承したものや列挙できないものは入りません。数字に見えるキーが先に来る理由、配列に戻す方法まで実行して確かめます…

✓operator/optional-chaining

?. と ?? — 無いかもしれない値を安全に読む

?. は null と undefined のときだけ止まります。?? は 0 や空文字を既定値で潰しません。連鎖が丸ごと止まること、?. が守ってくれない場面…

✓operator/spread

スプレッド構文と残余 — ... の2つの意味

同じ ... が、広げる側と集める側で逆の意味になります。配列・オブジェクト・関数それぞれの使い方、後ろ勝ちの上書き、複製が1段しか効かない点までを実行して確か…

✓promise/promise

Promise — then / catch / finally と async / await

Promise は「あとで決まる値」を表します。3つの状態、then の繋がり方、途中で投げたときの流れ、 async 関数が必ず Promise を返すこと、…

✓regexp/test-match

正規表現で探す — test() と match() と matchAll()

あるかどうかだけなら test()、取り出すなら match()、全部取り出すなら matchAll() です。 g フラグを付けたときに戻り値の形が変わること…

✓string/replace

String.prototype.replace() と replaceAll()

replace() は文字列を渡すと最初の1つしか置き換えません。全部置き換える書き方、 $ が特別扱いされる落とし穴、関数で置き換える方法までを実行して確かめ…

✓string/split

String.prototype.split()

split() は文字列を区切って配列にします。見つからないとき、空文字で分けたとき、絵文字が壊れる理由、連続した区切りの扱いまで、実行して確かめます。

✓string/template

テンプレートリテラル — 値を埋める・改行する・加工する

バッククォートで囲むと値を埋め込め、改行もそのまま書けます。何を入れても文字列になること、オブジェクトが [object Object] になること、タグ付きテ…

✓string/trim-pad

trim() / padStart() / padEnd() / repeat()

前後の空白を落とす trim()、桁を揃える padStart() / padEnd()、繰り返す repeat()。全角空白も落ちること、長すぎると詰めないこ…

✓timer/set-timeout

setTimeout() / setInterval() — 後で動かす

0 ミリ秒を指定しても、いま動いている処理が終わるまで動きません。止め方、引数の渡し方、 var で書いたループが全部同じ値になる理由、待つ関数の作り方まで実行…

04エラー

エラー文から引く

✓assignment-to-constant-variable

TypeError: Assignment to constant variable.

const で宣言した変数に代入し直すと出ます。const が固定するのは「値」ではなく「結びつき」で、配列やオブジェクトの中身は変えられます。その線引きと直し…

✓await-is-only-valid-in-async

SyntaxError: await is only valid in async functions

await を書ける場所は決まっています。async を付け忘れた関数、コールバックの中、昔の書き方のファイル。それぞれの直し方と、直った後に起きやすい間違いま…

✓cannot-access-before-initialization

ReferenceError: Cannot access 'x' before initialization

let / const / class を宣言より前で使うと出ます。var との違い、typeof でも避けられない理由、外側の同名変数を隠して起きる場合まで、…

✓cannot-convert-undefined-or-null

TypeError: Cannot convert undefined or null to object

Object.keys() などに null や undefined を渡すと出ます。落ちるものと黙って通るものの違い、値がそこで null になった原因の追い…

✓cannot-read-properties-of-undefined

TypeError: Cannot read properties of undefined (reading 'x')

undefined のプロパティを読もうとしたときに出ます。原因を多い順に並べ、それぞれ直したコードを載せています。スタックトレースのどこを見るかも書いています…

✓converting-circular-structure

TypeError: Converting circular structure to JSON

自分自身を辿れるオブジェクトを JSON.stringify() に渡すと出ます。親子の相互参照、 DOM 要素、通信のオブジェクト。どこで輪になっているかの見…

✓invalid-array-length

RangeError: Invalid array length

new Array() や length への代入に、負の数・小数・NaN・大きすぎる数を渡すと出ます。許される範囲、new Array(3) と Array.…

✓is-not-a-function

TypeError: x is not a function

関数でないものを呼んだときに出ます。綴り違い、配列でない値、this の外れ、読み込み方の食い違いなど、原因を多い順に並べ、それぞれ直したコードを載せています。

✓is-not-defined

ReferenceError: x is not defined

宣言していない名前を読もうとしたときに出ます。綴り違い、読み込み順、スコープの外、 Node とブラウザで存在しないもの。原因を多い順に並べ、それぞれ直したコー…

✓is-not-iterable

TypeError: x is not iterable

for...of やスプレッドや分割代入に、回せないものを渡したときに出ます。素のオブジェクト、null、通信の結果。原因を多い順に並べ、それぞれ直したコードを…

✓maximum-call-stack

RangeError: Maximum call stack size exceeded

関数の呼び出しが深くなりすぎたときに出ます。ほとんどは終わらない再帰です。止まる条件の書き忘れ、相互に呼び合う形、大きな配列の展開まで、原因別に直し方をまとめま…

✓unexpected-end-of-json

SyntaxError: Unexpected end of JSON input

JSON.parse に渡した文字列が途中で終わっているときに出ます。空の応答、204、途中で切れた本文、二重に読んだ本文。原因を多い順に並べ、落ちない受け取り…

✓unexpected-token

SyntaxError: Unexpected token

構文として読めなかったときに出ます。エラーの位置は壊れた場所ではなく気づいた場所です。 JSON.parse で出る場合が特に多く、その見分け方と直し方までまと…

05なぜ

仕組みの理由

✓float-precision

なぜ 0.1 + 0.2 は 0.30000000000000004 になるのか

2進数では 0.1 を正確に表せないためです。JavaScript 固有の問題ではありません。どこまで正確なのか、安全な比べ方、お金の扱い方までを実行して確かめ…

✓nan-equality

なぜ NaN === NaN は false なのか

NaN は特定の値ではなく「数値として表せなかった」という印です。そのため === では等しくなりません。includes や Set では等しく扱われる理由も…

✓semicolon-asi

なぜセミコロンを省いても動くのに、たまに壊れるのか

処理系が改行のところにセミコロンを補っています。ただし補わない場合があり、そこだけ意味が変わります。return の後の改行、行頭の括弧。実際に壊して確かめます…

✓strict-equality

なぜ == ではなく === を使うのか

== は型を揃えてから比べるため、0 == '' が true になるなど直感と外れます。推移律が成り立たない具体例、== を使ってよい唯一の場面、Object…

✓this-binding

なぜ this は呼び方で変わるのか

this は書いた場所ではなく、呼ばれ方で決まります。メソッドから取り出すと外れる理由、 strict モードでの違い、アロー関数だけが例外である仕組みを、実行…

✓typeof-null

なぜ typeof null は "object" なのか

仕様がそう定めているからです。理由は仕様に書かれていません。null を見分ける正しい方法、 undefined との使い分け、Object.prototype…

✓zero-index

なぜ配列の番号は0から始まるのか

先頭からの距離を番号にしているからです。0 始まりだと slice の範囲、長さの計算、ループの条件がすべて足し算・引き算だけで揃います。1 始まりで書いたとき…