JavaScript 面接の質問
JavaScript面接では、言語の核となるメカニズム — スコープ、クロージャ、非同期動作、プロトタイプチェーン — の理解度が試され、多くの場合、短いコーディング課題が出題されます。
JavaScript 面接で問われる内容
スコープとクロージャ
レキシカルスコープ、クロージャ、ホイスティング、テンポラルデッドゾーン。
非同期とイベントループ
コールバック、Promise、async/await、マイクロタスクとマクロタスク。
thisとプロトタイプ
thisのバインド方法、call/apply/bind、プロトタイプ継承。
型と型変換
==と===、真偽値、よくある型変換の落とし穴。
JavaScript 面接の質問例
- クロージャとは何か、実際の使用例を挙げてください。良い回答が押さえる点
- 関数とそのレキシカル環境の組み合わせ
- スコープチェーンによる変数保持
- プライベート変数や関数ファクトリでの利用
- メモリリークの注意点
サンプル回答を見る
クロージャとは、関数が自身が定義されたスコープ内の変数を保持し続ける仕組みです。関数が作成されるときにその関数はレキシカルスコープを閉じ込め(クロージャ)、関数がどこで実行されてもそのスコープにアクセスできます。実際の使用例として、カウンターファクトリが挙げられます。function createCounter() { let count = 0; return function() { return ++count; }; } のようにすると、返された関数はcount変数を保持し続け、呼び出すたびにカウントアップします。これにより、プライベートな状態を持つ関数を作成できます。また、モジュールパターンやコールバックでの状態保持にも利用されます。注意点として、クロージャは変数を解放しないため、不必要に使い続けるとメモリリークの原因になることがあります。
- イベントループ、マイクロタスク、マクロタスクについて説明してください。良い回答が押さえる点
- シングルスレッド
- コールスタックとキュー
- setTimeout, Promiseの動作
- マイクロタスクの優先順位
サンプル回答を見る
イベントループはJavaScriptのランタイムが非同期処理を管理する仕組みです。JavaScriptはシングルスレッドで動作し、コールスタック、マイクロタスクキュー、マクロタスクキュー(タスクキュー)を用いてタスクを実行します。マクロタスクはsetTimeoutやsetInterval、I/Oイベントなど、マイクロタスクはPromiseのthen/catch/finally、MutationObserverなどです。イベントループはコールスタックが空になると、まずマイクロタスクキューからすべてのタスクを処理し、その後マクロタスクキューから一つ取り出して実行します。この順序により、Promiseのコールバックは通常のsetTimeoutより先に実行されます。例えば、setTimeout(() => console.log('1'), 0)とPromise.resolve().then(() => console.log('2'))があると、出力は'2'の後に'1'となります。これにより、非同期処理の実行順序を理解し、バグを防ぐことが重要です。
- ==と===の違いは何ですか?また、==が許容されるのはどのような場合ですか?良い回答が押さえる点
- 厳格な等価演算子===は型変換なし
- ==は型変換を伴う
- nullとundefinedの扱い
- パフォーマンスと可読性
サンプル回答を見る
===は厳格な等価演算子で、型変換を行わずに値を比較します。つまり、値が同一で型も同じでなければtrueになりません。一方、==は抽象等価演算子で、比較前に型変換(型強制)を行います。例えば、'5' == 5はtrueですが、'5' === 5はfalseです。==が許容される場面としては、nullとundefinedを同時にチェックする場合(x == nullはxがnullまたはundefinedの場合にtrue)や、ユーザー入力などで型が不確定な場合に簡潔に書けることがあります。ただし、型変換のルールは複雑で意図しないバグを生みやすいため、基本的には===を使うのが安全です。チームのコーディング規約やプロジェクトの方針によっては、==を禁止していることも多いです。長期的なメンテナンス性を考えると、===を推奨します。
- `this`はどのように決定され、call/apply/bindはそれをどのように変更しますか?良い回答が押さえる点
- 実行コンテキストに応じたthisの決定
- 暗黙的な束縛(メソッド呼び出し)
- 明示的な束縛(call, apply, bind)
- アロー関数のthisはレキシカル
サンプル回答を見る
thisは関数の呼び出し方によって値が決まります。通常の関数では、オブジェクトのメソッドとして呼ばれるとそのオブジェクトがthisになります。グローバルスコープで呼ばれると、strictモードではundefined、非strictモードではグローバルオブジェクト(ブラウザではwindow)です。callとapplyは関数を呼び出す際にthisを指定します。callは引数をそのまま渡し、applyは配列で渡します。bindは新しい関数を返し、その関数のthisを永続的に固定します。例えば、function greet() { console.log(this.name); } として、greet.call({name:'Alice'})のように使います。アロー関数は自身のthisを持たず、外側のスコープのthisを継承します。これにより、コールバック内で意図したthisを維持しやすくなります。ただし、アロー関数に対してcall/apply/bindを適用してもthisを変更できない点に注意が必要です。
- デバウンス(またはスロットル)関数を実装してください。良い回答が押さえる点
- デバウンスの実装
- タイマーのクリアと再設定
- leadingとtrailingの違い
- スロットルとの比較
サンプル回答を見る
デバウンスは、連続して発生するイベントの最後だけを実行するためのテクニックです。実装では、設定した待機時間内に新しい呼び出しがあるたびにタイマーをリセットし、最後の呼び出しからの待機時間が経過したら関数を実行します。最も基本的な実装は、クロージャを使ってタイマーIDを保持し、毎回clearTimeoutとsetTimeoutを行います。注意点として、leadingオプション(最初の呼び出しを即座に実行する)やtrailingオプション(最後の呼び出しを実行する)を実装することもあります。スロットルは一定時間内に一度だけ実行する点で異なります。パフォーマンス向上のために、検索バーの入力やウィンドウリサイズなどでよく使われます。
参考コードjavascript function debounce(func, wait, immediate = false) { let timeout; return function executedFunction(...args) { const context = this; const callNow = immediate && !timeout; const later = function() { timeout = null; if (!immediate) func.apply(context, args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); if (callNow) func.apply(context, args); }; } // 使用例 const debouncedSearch = debounce(() => { console.log('検索実行'); }, 500); - var、let、constの違いは何ですか?良い回答が押さえる点
- varは関数スコープ、let/constはブロックスコープ
- varの巻き上げと初期化
- let/constのTDZ(一時的デッドゾーン)
- constは再代入不可、オブジェクトのプロパティは変更可
サンプル回答を見る
varは関数スコープを持ち、再宣言と更新が可能です。変数はスコープの先頭に巻き上げられ(hoisting)、undefinedで初期化されます。letとconstはブロックスコープを持ちます。letは再代入可能、constは再代入不可能です。ただし、constで宣言されたオブジェクトのプロパティの変更は可能です。letとconstは巻き上げられますが、初期化されないため、宣言前にアクセスするとReferenceErrorが発生します(一時的デッドゾーン)。最近のJavaScriptでは、varよりもlet/constの使用が推奨されます。constをデフォルトとし、再代入が必要な場合のみletを使うのがベストプラクティスです。
準備方法
- トリッキーなスニペット(ループ内のクロージャ、非同期の順序)の出力を予測できるようにしましょう。
- デバウンス、スロットル、簡単なPromiseをゼロから実装する練習をしましょう。
- 非同期の順序を正確に説明できるように、イベントループを十分に理解しましょう。
- モダンな機能(let/const、アロー関数、分割代入、モジュール)とその存在理由を理解しましょう。
よくある質問
JavaScriptはReactとは別に質問されますか?
はい — 多くの面接では、フレームワークとは別に、クロージャ、非同期、`this` に関する純粋なJavaScriptのラウンドが含まれます。
TypeScriptは必要ですか?
フロントエンド職ではますます必要ですが、核となるJavaScriptの仕組みが面接官がテストする基盤であることに変わりはありません。
どのJavaScriptのトピックが最もよく出ますか?
クロージャ、イベントループとPromise、`this`のバインド、デバウンスやスロットルなどのユーティリティの実装。
JavaScript面接の練習方法は?
スニペットの出力を予測し、時間制限のある中で小さなユーティリティを実装しましょう。Offerslyはあなたの履歴書に合わせたJavaScriptの質問を生成できます。
JavaScript の質問をAIで練習、瞬時にフィードバック
履歴書をアップロードして、パーソナライズされた模擬面接を受け、改善点を確認 — 無料で始められます。