この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:3
ページ更新者:atom
更新日時:2026-05-17 06:28:41

タイトル: Uncaught TypeError: Illegal invocation

エラー内容

Uncaught TypeError: Illegal invocation

JavaScriptで発生する例外で、関数が本来想定するthisバインディングや実行コンテキストから切り離されて呼ばれた場合に出ます。jQueryなどでフォームデータをファイル付き送信しようとしたとき、Ajaxの内部処理でDOMオブジェクトが想定外の形に変換されることが原因となるケースが特に多いです。

発生条件 / 原因

  • jQuery $.ajax でファイル送信: FormData を渡しているのに、jQuery側がオブジェクトを文字列化しようとして失敗(最頻出)
  • ネイティブ関数の this 外し: const log = console.log; log("hi"); のように、メソッドを変数代入してから呼ぶと this が外れて発生する
  • setTimeout / setInterval の引数誤り: setTimeout(button.click, 100)this が外れる
  • Window / Document のメソッドを別オブジェクトで呼ぶ: window.alert.call({}, "...")

対処法

1. ajaxでファイル送信する場合

ajaxのパラメータに以下の文言を追加して、ajaxによる送信データの成形を無効化する。

processData:false

あわせて contentType: false も指定するのが定石です。完成形は次の通り。

const formData = new FormData();
formData.append('file', document.querySelector('#file').files[0]);

$.ajax({
    url: '/upload',
    type: 'POST',
    data: formData,
    processData: false,
    contentType: false
});

2. メソッドを変数代入して使う場合

変数化したメソッドは this が外れます。bind で固定するか、関数化して呼びます。

// NG: log() 内部の this が undefined になり Illegal invocation
const log = console.log;
log("hi");

// OK: bind で this を固定
const log = console.log.bind(console);
log("hi");

// OK: 関数として呼ぶ
const log = (...args) => console.log(...args);
log("hi");

3. setTimeout でメソッドを渡す場合

// NG
setTimeout(button.click, 100);

// OK: アロー関数で包む
setTimeout(() => button.click(), 100);

// OK: bind
setTimeout(button.click.bind(button), 100);

注意点

  • Illegal invocation の本質は「ネイティブAPIに必要なthisが無い」。アプリ側のロジックエラーではなく、呼び出し方の問題
  • FormDataを使うAjaxでは processData:falsecontentType:false の両方が必須
  • jQueryなしのモダンな書き方なら fetch(url, {method:'POST', body: formData}) でこのエラーは出にくい

関連