はじめに
定義した関数 is not a function
このエラーメッセージは何を意味し、どう解決するのか、実際に出会した問題とそれを解消してわかったことを簡単にまとめていきます。
前提
Emailアドレスを指定したチェックルールに基づいてチェックする関数を作成しました。
そのときに実装したコードが以下になります。
const doesNotStartAtWithAt = email => email[0] != "@";
const doesNotHaveSpace = email => !/\s/.test(email);
const hasUppercaseAndLowercase = email => /[a-z]/.test(email) && /[A-Z]/.test(email);
function emailValidation(f, email){
return f(email) ? "Email is correct." : "Email is not correct.";
}
module.exports = { doesNotStartAtWithAt, doesNotHaveSpace, hasUppercaseAndLowercase, emailValidation };
const { doesNotStartAtWithAt, doesNotHaveSpace, hasUppercaseAndLowercase, emailValidation } = require('../src/validation.js');
const tests = {
"case1" : {
"input" : {
"validator" : doesNotStartAtWithAt,
"email" : "@gmail.com"
},
"output" : "Email is not correct."
},
"case2" : {
"input" : {
"validator" : doesNotHaveSpace,
"email" : "kkk@gmail.com"
},
"output" : "Email is correct."
},
...
}
for(const [key, test] of Object.entries(tests)){
const { validator, email } = test.input;
const output = emailValidation(validator(email));
const expected = test.output;
const result = (output === expected) ? "Success" : "Failure";
console.log(`Test ${key}: ${result}`);
}
エラーメッセージ
/Users/mavo/project/algorithm-solutions/HigherOrderFunc/problems/02_validation/js/src/validation.js:6
return f(email) ? "Email is correct." : "Email is not correct.";
^
TypeError: f is not a function
at emailValidation (/Users/mavo/project/algorithm-solutions/HigherOrderFunc/problems/02_validation/js/src/validation.js:6:12)
at Object.<anonymous> (/Users/mavo/project/algorithm-solutions/HigherOrderFunc/problems/02_validation/js/tests/validationTest.js:64:20)
at Module._compile (node:internal/modules/cjs/loader:1369:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1427:10)
at Module.load (node:internal/modules/cjs/loader:1206:32)
at Module._load (node:internal/modules/cjs/loader:1022:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:135:12)
at node:internal/main/run_main_module:28:49
Node.js v20.12.2
エラーメッセージの意味
TypeError: f is not a function
ここからわかること
- 値の型が期待される型と一致しない
- fは関数ではない
関数でないものを、関数呼び出ししようとした際に発生するエラーです。また適切な関数が定義されていることを期待されているが、定義されていない場合も発生します。
関数名のタイプミスをしていないか確認してみましょう。また、呼び出そうとしてるオブジェクトがそのメソッドを持っているかどうかも確認してみてください。
※https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Errors/Not_a_function より引用
エラーメッセージから導ける仮説
- 関数名のタイプミス
- 呼び出しているものが関数ではない
- メソッドが存在しない(今回のケースではオブジェクトは使用していないので除外)
原因
関数への引数の渡し方に問題があり、関数の要件を満たしていなかったこと
const output = emailValidation(validator(email));
emailValidation() は関数と文字列を引数にとりますが、validator()の引数に文字列を入れた結果を格納してしまっていました。
解決策
emailValidation()に関数と文字列を渡す
const output = emailValidation(validator(email));
const output = emailValidation(validator, email);
まとめ
今回は、~ is not a function というエラーメッセージの解決法の一部を実体験を基に紹介させていただきました。
JavaScriptでは、function() のように括弧 () を付けて呼び出すと、JavaScriptエンジンはそれが関数であると期待します。
しかし、呼び出そうとした対象( ~ の部分)が、実際には関数ではなく、文字列、オブジェクト、undefinedなどだった場合に、このエラーが発生するようです。
今回のケースでは、関数を呼び出したつもりが、引数が定義した関数の引数ではなかったためにエラーが発生していました。
この他にも、タイプミスや予期しない型だったりとエラーの要因が状況によって変わりますので、まずはメッセージを丁寧に読んでいき、仮説から検証していきましょう!
最後までお読みいただき、ありがとうございました。
参考URL