JavaScriptガイド
言語内部、ランタイム、フレームワーク — コードレベルで動作原理整理
⚙️ 言語内部
イベントループ — setTimeout(fn, 0)が即座に実行されない理由
Call Stack、Task Queue、Microtask Queueの実行順序
JavaScriptはシングルスレッドなのに非同期が可能な理由:イベントループがCall Stackが空の時にTask Queueからコールバックを取り出して実行するから。Promiseのthenは Microtask Queueに入り通常Taskより先に実行される。
クロージャとスコープチェーン — 関数が外部変数を記憶する原理
Lexical Environmentオブジェクトが作るスコープチェーンの内部構造
クロージャは関数が生成された時点のLexical Environmentをキャプチャして保存するもの。関数が外部スコープの変数を参照すると、そのLexical Environmentオブジェクトがガベージコレクションされず生き残る。
プロトタイプチェーン — classがなかった時代の継承
__proto__、prototype、Object.create()の関係
JavaScriptのclassはシンタクティックシュガー。内部的にプロトタイプチェーンで動作する。オブジェクトの__proto__が親オブジェクトを指し、プロパティが見つからなければチェーンを辿り上がる。
Promise内部 — then()がMicrotask Queueに入る過程
Promiseの3つの状態とthenableチェーンの実行メカニズム
Promiseはpending/fulfilled/rejectedの3状態を持つ状態マシン。resolve()呼び出し時にthenに登録されたコールバックがMicrotask Queueに入る。async/awaitはPromiseのシンタクティックシュガー。
🔷 TypeScript
TypeScript型システム — コンパイル後全て消える
構造的型付け(Structural Typing)とは何か、Javaの名目的型付けとなぜ違うか
TypeScriptの型はコンパイル時にのみ存在し、ランタイムJavaScriptには痕跡も残らない。Javaと違い「名前」ではなく「構造」で型互換性を判断する(Structural Typing)。
TypeScriptジェネリクスパターン — Tが何か一発で理解する
関数/クラス/インターフェースで「後で決まる型」を使う方法
Tは「まだ分からない型」のプレースホルダー。関数呼び出し時点でTが具体型に決まる。ジェネリクスなしではanyを使うことになり、anyを使うとTypeScriptの意味がなくなる。
判別ユニオン — TypeScriptでenumの代わりに使うパターン
typeフィールドで分岐するとTypeScriptが各分岐の型を自動的に絞る
共通フィールド(discriminant)でユニオン型を区別するパターン。switch/ifで分岐するとTypeScriptが該当分岐で型を自動的に絞る。Rustのenum + matchに近い効果。
🟢 Node.js
Node.jsイベントループ — ブラウザと異なる6段階フェーズ
timers → pending → idle → poll → check → close、そしてprocess.nextTickの位置
Node.jsのイベントループ(libuv)はブラウザと違い6つのフェーズを巡回する。setTimeoutはtimersフェーズ、setImmediateはcheckフェーズ、process.nextTickは全フェーズ間で実行。
Node.js Streams — 大容量データをメモリ爆発なしで処理する方法
Readable、Writable、Transform + backpressureの動作原理
10GBファイルをfs.readFile()で読むとメモリが爆発する。Streamはデータをchunk単位で流してメモリを一定に維持。Backpressureは消費者が遅い時に生産者を止めるメカニズム。
ESM vs CommonJS — requireとimportが違う理由
同期ロード vs 非同期ロード、そして"type": "module"の意味
CommonJS(require)は同期ロード、ESM(import)は非同期ロード。Node.jsで両システムが共存することで生じる互換性問題と解決策。
🌐 ブラウザAPI
Web Workers — JavaScriptでマルチスレッドを使う方法
postMessageの構造化複製(Structured Clone)とSharedArrayBuffer
Web Workerはメインスレッドと別のスレッドでJavaScriptを実行する。DOMアクセス不可、postMessageで通信。重い計算をWorkerに回せばUIが止まらない。
Service Workerライフサイクル — install、activate、fetchの順序
PWAの核心、オフラインキャッシュが動作するメカニズム
Service Workerはブラウザとネットワークの間にプロキシとして動作する。install→activate→fetchの順でライフサイクルが進行し、Cache APIでリソースを保存してオフラインでもアプリが動作するようにする。
Intersection Observer — スクロールイベントなしで要素の可視性を検出
lazy loading、無限スクロール、アニメーショントリガーの高性能実装方法
Intersection Observerは要素がビューポートに入る/出る時にコールバックを実行する。scrollイベント+getBoundingClientRect()より性能が良く、ブラウザが最適化されたタイミングで実行。
Popover API — JavaScriptなしでツールチップが作れるようになった理由
popover属性1つで開閉・Escキー・アクセシビリティが自動動作するブラウザネイティブUI
従来のツールチップにはイベントリスナー、状態管理、ARIA属性の手動同期が全て必要だった。Popover APIはこれをブラウザネイティブで置き換える。popover属性とpopovertargetだけで開閉・Escキー・キーボードナビゲーションが自動動作。
🔬 オープンソース分析
background-removal-js — ブラウザで背景除去が動く本当の仕組み
IS-Net ONNXモデル + WASM推論 + Canvas API、サーバーなしでクライアント完結するパイプライン
imglyのbackground-removal-jsは画像を入れると背景が透明なPNGが出るライブラリ。ONNX Runtime WASMでブラウザ内でIS-Netモデルを実行。サーバー不要。Star 7千。
OpenGenerativeUI — ClaudeのVisual Artifactsをオープンソースで再現した構造
CopilotKit Deep Agents + LangGraph + サンドボックスiframe、AIがチャート・3D・ダイアグラムをリアルタイム生成するパイプライン
CopilotKitがClaudeのインタラクティブVisual Artifacts生成をオープンソースで実装した。Next.js 16フロントエンド + Python LangGraphエージェントがHTML/SVG/Chart.js/Three.jsコードを生成、サンドボックスiframeでレンダリング。MITライセンス。Star 1.1K。