() を付けて呼んだものが、関数ではなかったときに出ます。
const user = { name: 'あかり' };
console.log(user.getName());プロパティは読めています。 user.getName は undefined で、
それを呼ぼうとして落ちました。
Cannot read properties of undefined
とは止まる場所が違います。あちらは1つ手前が undefined のときです。
const nums = [3, 1, 2];
console.log(nums.lenght);
console.log(nums.foreach(n => n));const text = 'あいうえお';
console.log(text.push('か'));まず typeof で確かめてください。 呼ぶ前に何が入っているかを見れば、原因はすぐ分かります。
原因1: 名前が違う(いちばん多い)
大文字・小文字、単数・複数、綴り。エラー文にその名前が出ています。
length を lenght、forEach を foreach と書いています。
| よくある間違い | 正しい名前 |
|---|---|
foreach |
forEach |
toLowercase |
toLowerCase |
lenght |
length |
push() を文字列に |
文字列に push は無い |
エラー文の名前をそのまま検索してください。 綴り違いなら1秒で分かります。
原因2: そのものに、その関数が無い
型が違えば持っているものも違います。
const scores = { math: 80, english: 95 };
console.log(scores.map(v => v * 2));文字列は変更できないので push() はありません。繋ぐなら + か concat() です。
function calc(sum) {
return sum();
}
console.log(calc(10));let handler = () => 'ok';
handler = 'ok';
console.log(handler());似た形で間違えやすいものを並べます。
class Counter {
constructor() {
this.n = 0;
}
add() {
this.n += 1;
return this.n;
}
}
const c = new Counter();
const add = c.add;
console.log(add());const obj = {
items: [1, 2],
show() {
return this.items.join(',');
},
};
const show = obj.show;
console.log(show());map() は配列にしかありません。オブジェクトや文字列にはありません。
document がここで undefined なのは、この実行環境が画面を持たないためです。ブラウザなら object になります。
配列のつもりが配列でない
Object.keys() などで配列にしてから使います。
// 名前付きで書き出しているのに、既定として読み込んだ
import utils from './utils.js';
utils.format(); // utils は undefined になり得る
// 正しくは
import { format } from './utils.js';
format();function greet() {
return 'こんにちは';
}
console.log(greet()());原因3: 同じ名前で上書きした
変数や引数が、関数と同じ名前になっていることがあります。
sum は引数で受け取った 10 です。関数ではありません。
同じことは、あとから代入した場合にも起きます。
原因4: this が外れている
メソッドを関数として取り出すと、this が付いてきません。
この例では別のエラーになりますが、原因は同じです。
this が外れると、this.何か() が undefined is not a function になることもあります。
読んでいるものが items ではなく join になっています。ここに違いが出ます。
| 書いた場所 | 外れたときの this |
落ちる場所 |
|---|---|---|
class の中 |
undefined(クラスは常に strict) |
this.n の時点 |
| オブジェクトリテラルのメソッド(strict でない) | globalThis |
this.items は undefined になり、その .join |
上のクラスの例が reading 'n' で、こちらが reading 'join' なのはこのためです。
モジュール(import / export のファイル)は常に strict なので、
実際のコードではクラスと同じく this が undefined になります。
このページの実行環境は strict ではないため、globalThis のほうの結果が出ています。
直しかた
呼び出しごと渡すか、bind() で結びつけます。
原因5: 読み込み方が食い違っている
この環境では再現できません(ブラウザや Node のモジュール読み込みの話です)。 起きるのは次のような形です。
export defaultとexport { … }を取り違えている- CommonJS(
module.exports)と ES Modules(export)が混ざっている - 読み込む前に呼んでいる(
<script>の位置、async/defer)
console.log(読み込んだもの) を1行入れて、何が入っているかを見てください。
undefined なら読み込み側、{} なら書き出し側の問題です。
括弧を余分に付けていないか
関数が返した値を、もう一度呼んでしまう間違いです。
エラー文が greet(...) is not a function になります。
(...) が付いていたら、呼んだ結果を呼んでいるという合図です。
関数を返す関数なら、これは正しい書き方です。
処理系によって文言が違う
| 処理系 | 文言 |
|---|---|
| Node / Chrome(V8) | user.getName is not a function |
| Firefox(SpiderMonkey) | user.getName is not a function |
| Safari(JavaScriptCore) | user.getName is not a function |
この文言はどの処理系でもほぼ同じです。読み替えの心配は要りません。
このページの実行結果は Node 22.22.3 のものです。
探しかたの順序
- エラー文の名前を見る。
x is not a functionのxがそのまま手がかり - 呼ぶ直前で
typeofを出す。undefinedなら無い、objectなら別物 undefinedだったら … 綴り違い(原因1)/型が違う(原因2)/読み込み(原因5)objectや数値だったら … 同じ名前で上書きした(原因3)(...)が付いていたら … 括弧が多い
Object.keys() で実際に何を持っているかを並べると、綴り違いはすぐ見つかります。
ほかのエラー
- SyntaxError: Unexpected token … 構文として読めない。1行も実行されない
- RangeError: Maximum call stack size exceeded … 呼び出しが深すぎる。ほとんどは終わらない再帰
- Cannot read properties of undefined
… 1つ手前が
undefinedだった