JavaScriptでの’ReferenceError’、’SyntaxError’、’TypeError’のトラブルシューティング方法
イントロダクション
JavaScriptは、フロントエンドおよびバックエンドの開発で使用されるプログラミング言語です。JavaScriptを使う際には、エラーメッセージの解読が少し難しいかもしれません。アプリケーション内の問題をトラブルシューティングする際に、エラーメッセージが何を指しているのかを理解することは重要です。幸いなことに、現代のブラウザには組み込みのデバッグツールが付属しており、これによって助けを受けることができます。各ブラウザは、視覚的な表現においてエラーメッセージを異なる方法で扱いますが、それでもエラーメッセージはJavaScriptコードに何が起こっているかを知る手がかりになります。
このチュートリアルでは、ブラウザ環境で表示される3つの一般的なJavaScriptエラータイプについて説明します:ReferenceError、SyntaxError、およびTypeError。一緒に進めるためには、JavaScriptと開発者コンソールの理解が必要です。
私たちのJavaScriptコーディングチュートリアルでは、JavaScriptについてさらに多くのことを学ぶことができます。また、JavaScript開発者コンソールの使い方については当社のチュートリアルで学ぶことができます。
以下の例は網羅的ではありませんが、遭遇する可能性のある一般的なエラーメッセージの入門として機能します。さらに、例に示されているエラーメッセージはChromeウェブブラウザからのものです。FirefoxやEdgeから受け取るエラーメッセージにはわずかに異なるメッセージングが含まれる場合もありますが、エラーの種類は同じです。
JavaScriptのエラータイプの理解
JavaScriptのエラーは、エラーオブジェクトに基づいています。これは、発生したエラーのタイプに関する情報が含まれた組み込みオブジェクトであり、その後に原因の可能性について詳細なメッセージが続きます。たとえば、次のようなエラーメッセージに遭遇することがあります。
VM170:1 Uncaught ReferenceError: shark is not defined
at <anonymous>:1:1
このエラーメッセージを解析すると、特定されたエラーはReferenceErrorのタイプであることが分かります。セミコロンの後ろにはエラーメッセージがあり、そのエラーメッセージは「sharkは定義されていません」と述べています。このメッセージの最後の行には、エラーがコードの1:1の場所で発生していることが詳細に記載されています。
ブラウザでエラーが検知された場合、エラーのタイプとメッセージによって問題が示されます。これらの情報を基にして、受け取ったエラータイプとメッセージに基づいてデバッグの方法を判断することができます。
ReferenceErrorを理解する
未作成の変数にアクセスしようとすると、ReferenceErrorが発生します。また、初期化する前に変数を呼び出すと、同様にReferenceErrorが発生します。
未定義の変数に出くわすこと
例えば、console.log()を実行する際に変数名を誤って入力すると、ReferenceErrorが表示されます。
let sammy = 'A Shark dreaming of the cloud.';
console.log(sammmy);
Uncaught ReferenceError: sammmy is not defined at <anonymous>:1:13
変数「sammmy」は存在せず、定義されていません。このエラーを修正するために、変数を正しいスペルに更新してコマンドを再実行することができます。成功すると、エラーメッセージは表示されません。全体的に、コードのスペルミスを確認することで未定義の変数エラーを防ぐことができます。
変数が宣言される前にアクセスする
同様に、コード内で変数が宣言される前にアクセスしようとすると、次のエラーが発生する可能性があります。
function sharkName() {
console.log(shark);
let shark = 'sammy';
}
VM223:2 Uncaught ReferenceError: Cannot access ‘shark’ before initialization at sharkName (<anonymous>:2:17) at <anonymous>:1:1
この例では、shark変数が宣言される前にconsole.log(shark)が実行されるため、エラーが発生します。一般的に、アクセスする前に変数を宣言することが良いプラクティスです。
Note
コードの例を修正するために、console.log()コマンドを実行する前にshark変数を宣言してください。
function sharkName() {
let shark = 'sammy';
console.log(shark);
}
ReferenceErrorは、変数とスコープにしばしば関連しています。このチュートリアルの範囲を超えて、JavaScriptの変数、スコープ、および巻き上げについては、Understanding Variables, Scope, and Hoisting in JavaScriptのチュートリアルで詳しく学ぶことができます。
構文エラーを理解する
JavaScriptのインタープリターがコードを調べる際、言語仕様に従わないコードが見つかるとSyntaxErrorが発生する可能性があります。もし発生した場合、コードの実行は停止され、構文に関するメッセージが表示されます。
コードの欠落している箇所
例えば、関数を書いている際に、コードを囲むためにカッコ ) を忘れると、抜けている部分に関する具体的なメッセージが記された SyntaxError が表示されます。
function sammy(animal) {
if(animal == 'shark'){
return `I'm cool`;
} else {
return `You're cool`;
}
}
sammy('shark';
Uncaught SyntaxError: missing ) after argument list
幸いなことに、エラーメッセージはコード内の不足している要素を指定しています。この例では、sammy関数の呼び出しには閉じる)カッコが不足しています。
. . .
sammy('shark');
関数の終わりのカーリーブレース(})や配列のブラケット(])を省略すると、同様のエラーが発生します。関数、配列、オブジェクトを適切に閉じることを確認してください。
同じ変数名を宣言する
以下の例では、関数のパラメータと関数本体内で同じ変数名を使用する場合にも、このエラーに遭遇することがあります。
function sammy(animal) {
let animal = 'shark';
}
VM132:2 Uncaught SyntaxError: Identifier ‘animal’ has already been declared
エラーを修正するためには、関数本体内で一意で具体的な変数名を作成することを確認してください。新しい変数名(例えばanimalTypeなど)を宣言することで、関数のパラメーターと本体内のlet変数との競合を解消することができます。
function sammy(animal) {
let animalType = 'shark';
}
関数本体内でパラメータを変更したり使用したい場合は、同じ変数名を持つ変数宣言を使用しないでください。例えば、本体内のlet宣言を削除することができます。
function sammy(animal) {
animal = 'shark';
}
関数本体内外で変数を扱う場合には、ユニークな名前を付けることを確認してください。関数のパラメータにアクセスする際には、letのような変数宣言なしに関数本体内でそれを使用することができます。
予期しないトークンの特定
コードには、]や}といった括弧を見落とすように、時には小さなが重要な追加が必要になることがあります。例えば:
let sharkCount = 0;
function sammy() {
sharkCount+;
console.log(sharkCount);
}
Uncaught SyntaxError: Unexpected token ‘;’
この例での追加要素は、関数本体内のsharkCountの後にある「+」プラス記号です。
. . .
function sammy() {
sharkCount++;
console.log(sharkCount);
}
SyntaxError: Unexpected tokenが発生した場合は、プラス記号(+)など、演算子が不足しているか追加されていないかをコードを再確認してください。
TypeErrorを理解する
TypeErrorは、関数や変数の値が予期しないタイプの場合に発生します。JavaScriptの異なるデータタイプについて詳しく学ぶには、弊社の「JavaScriptにおけるデータタイプの理解」チュートリアルをご覧ください。
オブジェクトに配列メソッドを使用する
一般的な間違いは、オブジェクトを反復処理するために配列メソッドを使用することです。例えば、.map() メソッドは配列固有のメソッドであるため、オブジェクトをループ処理することはできません。
const sharks = {
shark1: 'sammy',
shark2: 'shelly',
shark3: 'sheldon'
}
sharks.map((shark) => `Hello there ${shark}!`);
Uncaught TypeError: sharks.map is not a function at <anonymous>:1:8
前の例を修正するための1つのオプションは、for…inループを使用することです。これはオブジェクトデータ型に対して機能し、sharksオブジェクトから値を取得します。
const sharks = {
shark1: 'sammy',
shark2: 'shelly',
shark3: 'sheldon'
}
for (let key in sharks) {
console.log(`Hello there ${sharks[key]}!`);
}
選択肢としては、シャークオブジェクトを配列に変換して、.map()メソッドを使用することもできます。
const sharks = ['sammy', 'shelly', 'sheldon'];
sharks.map((shark) => `Hello there ${shark}!`);
異なる配列やオブジェクトを操作する際には、異なるメソッドを間違えることがあります。操作しているデータの種類に適したメソッドを使用しているか、再確認してください。
適切な破壊的分割法を使用する。
同様に、オブジェクトを配列の分割代入として反復しようとすると、TypeErrorが発生します。
const shark = {
name: 'sammy',
age: 12,
cloudPlatform: 'Silicon Cloud'
}
const [name, age, cloudPlatform] = sharks;
VM23:7 Uncaught TypeError: sharks is not iterable at <anonymous>:7:26
この問題を解決する方法の一つは、オブジェクトのキーに基づいて新しい変数を作成するためにオブジェクトの分割代入を使用することです。
const shark = {
name: 'sammy',
age: 12,
cloudPlatform: 'Silicon Cloud'
}
const {name, age, cloudPlatform} = shark;
console.log(name);
sammy
データを構築する方法によって、配列やオブジェクトを使用しているかによって、適切な方法を使用して値を取得することを確認してください。
結論
このチュートリアルでは、3つの一般的なJavaScriptのエラータイプと、それに関連するメッセージのいくつか、またそれらが発生した場合の一般的な問題のデバッグ方法について学びました。完全ではありませんが、JavaScriptとブラウザがコード内の問題を示すためにどのように連携するかについて洞察を得ることができました。
JavaScriptのオブジェクトメソッドと配列メソッドの使用方法について詳しく学ぶことで、それらのメソッドをどのように活用すれば良いかをより理解することができます。
Google Chrome DevToolsとVisual Studio Codeを使用したJavaScriptのデバッグ方法について、当社のチュートリアルでも詳しく学ぶことができます。