ホーム › エラー解決 › JavaScript › ReferenceError
JavaScript ERROR

JavaScript ReferenceError: is not defined の解決法

使おうとした変数や関数が見つからないときのエラーです。スペルミスと宣言忘れが主な原因です。

このエラーメッセージ

Uncaught ReferenceError: message is not defined

原因

❌ エラーになるコード

NG
console.log(message);
const message = "Hello";

✅ 修正したコード

OK
const message = "Hello";
console.log(message);
▶ 修正済みコードを実行エディタで開く
progoのJavaScript実行環境(インストール不要・登録不要)でその場で動作を確認できます。

解決のポイント

let・constで宣言した変数は、宣言より前で使うとReferenceErrorになります(一時的死角)。宣言してから使う順序にしましょう。名前の綴り・大文字小文字も一致させます。

「is not defined」と「undefined」は別物

混同しやすい2つですが、意味はまったく違います。ここを取り違えると直し方も変わります。

状態意味対処
x is not definedその名前自体がどこにも存在しない宣言する/綴りを直す/読み込み順を直す
x is undefined変数はあるが値が入っていない代入漏れ・戻り値なしの関数を疑う
Cannot access 'x' before initializationlet/constを宣言前に使った(TDZ)宣言をその使用より上へ移す

存在するかどうかだけ確かめたいときはtypeofを使います。typeofは未定義の名前に対してもエラーを出さない唯一の演算子です。

OK
// 未定義でもエラーにならない安全なチェック
if (typeof myLib !== "undefined") {
  console.log("myLibは読み込み済み");
} else {
  console.log("myLibはまだ存在しません");
}

名前別・よくある「is not defined」

出てきた名前でほぼ原因が決まります。自分のエラーの名前を探してください。

エラー原因と対処
$ is not defined
jQuery is not defined
jQuery本体を読み込む前に自分のJSが動いています。jQueryの<script>を先に置くか、自分のコードをdeferにします。
require is not definedブラウザ、またはESモジュール内でCommonJSのrequire()を使っています。importに書き換えます。
module is not defined
exports is not defined
同じくCommonJS前提のコードをブラウザ/ESモジュールで実行しています。exportに書き換えます。
process is not definedprocess.envはNode.jsのものです。ブラウザではビルドツール側の環境変数(Viteならimport.meta.env)を使います。
document is not defined
window is not defined
Node.jsやSSR(Next.jsのサーバー側)にはDOMがありません。ブラウザでのみ動く処理はuseEffect内やtypeof window !== "undefined"のガード内に置きます。
fetch is not defined古いNode.js(v18未満)です。Nodeを上げるかnode-fetchを導入します。
自作の関数名綴り・大文字小文字違い、またはファイルの読み込み漏れ。次の節を確認してください。

HTMLのonclickで「関数 is not defined」になる

<button onclick="doSomething()">が動かない場合、関数がグローバルに存在していないのが原因です。特に多いのが次の3つです。

NG
<script type="module">
  function hello() { alert("hi"); }  // onclickからは見えない
</script>
<button onclick="hello()">押す</button>
OK
<button id="btn">押す</button>
<script type="module">
  function hello() { alert("hi"); }
  document.getElementById("btn").addEventListener("click", hello);
</script>

onclick属性をやめてaddEventListenerで登録するのが最も確実です。どうしてもonclickを使うならwindow.hello = hello;と明示的にグローバルへ公開します。

スコープと巻き上げ(TDZ)

let・constで宣言した変数は、宣言行に到達するまで「一時的死角(TDZ)」にあり、触るとエラーになります。var・functionとの挙動の差を押さえておくと原因が読めます。

OK
// function宣言は巻き上げられるので前に呼べる
greet();
function greet() { console.log("hello"); }

// const/letの関数式は前に呼べない(ReferenceError)
// bye();
const bye = () => console.log("bye");
bye();

原因を特定する手順

下のエディタに貼り付けて実行すれば、宣言順やスコープの違いをその場で確認できます。

よくある質問

varなら大丈夫?
varは巻き上げられるためエラーにはなりませんが、値はundefinedになりバグの温床です。const/letを使い、宣言してから使う順序にしてください。
is not defined と undefined の違いは?
is not definedは「その名前自体が存在しない」、undefinedは「変数はあるが値が入っていない」です。前者は宣言・読み込みの問題、後者は代入の問題です。
$ is not defined と出ます
jQuery本体より先に自分のスクリプトが実行されています。jQueryのscriptタグを先に置くか、自分のコードにdefer属性を付けてください。
require is not defined と出ます
ブラウザやESモジュール内でCommonJSのrequire()を使っています。import文に書き換えるか、Node.jsで実行してください。
document is not defined / window is not defined
Node.jsやSSRのサーバー側にはDOMがありません。ブラウザ限定の処理はuseEffect内や typeof window !== "undefined" のガードの中に置いてください。
HTMLのonclickの関数が not defined になる
type="module"内の関数はグローバルではないためonclickから見えません。addEventListenerで登録するか、window.関数名 = 関数 で公開してください。
Cannot access before initialization は同じエラー?
同じReferenceErrorですが、名前は存在していて宣言前に触った(TDZ)ケースです。宣言をその使用より上へ移せば直ります。
存在チェックだけしたい場合は?
typeof を使います。typeof myLib !== "undefined" は未定義の名前でもエラーにならず判定できます。