🐡
[JavaScript] TypeError: "x" is not a function
JavaScript の例外 "is not a function" は、値を関数として呼び出そうとしたが、その値が実際には関数ではなかった場合に発生する。
エラーメッセージ
TypeError: Object doesn't support property or method {x} (Edge)
TypeError: "x" is not a function
原因
- 関数でないものを、関数呼び出ししようとした際に発生するエラー。また、適切な関数が定義されていることを期待されているが、定義されていない場合も発生する。
- 関数名のタイプミスをしていないか確認。また、呼び出そうとしてるオブジェクトがそのメソッドを持っているかどうかも確認。配列オブジェクトが持っているmap関数を、それを持たない通常のオブジェクトに対して呼び出そうとしている場合が、後者の例になる。
- 多くの組み込み関数はコールバック関数を必要とする。これらのメソッドを正しく呼び出すためには、関数を引数に指定する必要がある。
例
関数名のタイプミス
- 関数名を間違えている場合に発生する。
- このミスは非常に多く発生する。
const x = document.getElementByID('foo');
// TypeError: document.getElementByID is not a function
- 正しい関数名は getElementById
const x = document.getElementById('foo');
間違ったオブジェクトに対する関数呼び出し
- いくつかのメソッドは、引数に関数が指定されていることを期待していて、しかも特定のオブジェクトの上でのみ正しく動作するものがある。
- この典型例が Array.prototype.map() で、これは Array オブジェクトでのみ正しく動作する。
const obj = { a: 13, b: 37, c: 42 };
obj.map(function (num) {
return num * 2;
});
// TypeError: obj.map is not a function
- オブジェクトではなく、配列を利用。
const numbers = [1, 4, 9];
numbers.map(function (num) {
return num * 2;
});
// Array [2, 8, 18]
すでに存在するプロパティと名前を共有する関数
- クラスを作るとき、プロパティと関数が同じ名前になることがある。
- 関数を呼び出すと、コンパイラーは関数が存在するのをやめたように考える。
const Dog = function () {
this.age = 11;
this.color = 'black';
this.name = 'Ralph';
return this;
};
Dog.prototype.name = function (name) {
this.name = name;
return this;
};
const myNewDog = new Dog();
myNewDog.name('Cassidy'); //Uncaught TypeError: myNewDog.name is not a function
- 代わりに異なるプロパティ名を使う。
const Dog = function () {
this.age = 11;
this.color = 'black';
this.dogName = 'Ralph'; //Using this.dogName instead of .name
return this;
};
Dog.prototype.name = function (name) {
this.dogName = name;
return this;
};
const myNewDog = new Dog();
myNewDog.name('Cassidy'); //Dog { age: 11, color: 'black', dogName: 'Cassidy' }
乗算での括弧の使用
- 数学では、2×(3+5) を 2*(3+5) または単に2(3+5) と書くことができる。
- 後者を使用するとエラーが発生する。
const sixteen = 2(3 + 5);
alert('2 x (3 + 5) is ' + String(sixteen));
//Uncaught TypeError: 2 is not a function
- このコードは * 演算子を追加すると修正できる。
const sixteen = 2 * (3 + 5);
alert('2 x (3 + 5) is ' + String(sixteen));
//2 x (3 + 5) is 16
正しくエクスポートされたモジュールをインポートする
- 正しくモジュールをインポートしていることを確認。
- helpers ライブラリーの例 (helpers.js)
let helpers = function () { };
helpers.groupBy = function (objectArray, property) {
return objectArray.reduce(function (acc, obj) {
var key = obj[property];
if (!acc[key]) {
acc[key] = [];
}
acc[key].push(obj);
return acc;
},
{});
}
export default helpers;
- 正しい import の使い方 (App.js):
import helpers from './helpers'
参考
Discussion