JavaScriptでコーディング作業を行なっていると、誰もがエラーに遭遇するもの。コーディングエラーによっては、プロジェクトが一時中断してしまう可能性があります。

エラーを効率的に解決するには、エラーメッセージの意味を理解しなければなりません。

今回はJavaScriptの「Uncaught TypeError: Cannot set property」エラーを取り上げます。

エラーが発生するいくつかのシナリオと、それぞれの解決方法をご紹介します。最後に、変数がnullundefinedであるかを判断する方法についても触れていきます。

JavaScriptの「Uncaught TypeError: Cannot Set Property」の原因

typeerrorは、主に互換性のないデータ型を含む操作を行った時に発生します。「Uncaught TypeError: Cannot set property」エラーの場合は、nullの値を持つプロパティをDOM要素に割り当てようとして発生するJavaScriptエラーです。

このエラーは、以下のような原因で発生します。

  • scriptタグがマークアップ内の誤った位置に配置されている
  • DOM要素を参照する際の入力ミス
  • 未定義または無効なDOM要素にアクセスしようとしている

JavaScriptの「Uncaught TypeError: Cannot set property」エラーを解決する方法

それでは、上で挙げた3つの原因を掘り下げて、それぞれの解決方法をご紹介していきます。

理解しやすいよう、実用的なコード例を用いて見ていきましょう。

scriptタグの無効な配置

ウェブページが読み込まれる際、そのページに対応するJavaScriptコードも同時に読み込まれます。JavaScriptがDOM(Document Object Model)を認識する方法は、コード内のscriptタグの配置に依存します。

scriptタグをheadタグ内に置いたり、bodyタグ内のすべてのHTML要素の上に配置したりすると、DOMの準備ができる前にスクリプトが実行されます。

DOMの準備ができる前にJavaScriptが実行されると、DOMの完全な表現を取得することができません。つまり、DOM要素にリンクされた変数のほとんどがnullとして返されます。

以下は、このscriptタグの位置が原因で「Uncaught TypeError: Cannot set property」エラーが発生するコード例です。

<!DOCTYPE html>
<html>
  <head>
    <title>「Uncaught Typeerror」エラーの解決方法</title>
    <script src="app.js"></script>
  </head>
  <body>
    <h1 id="heading"></h1>
  </body>
</html>

headタグの中にscriptタグが配置されており、headingidを持つh1要素があります。

次に、h1要素にテキストを追加します。

let heading = document.getElementById('heading');
heading.textContent = 'This is a heading';
//Uncaught TypeError: Cannot set properties of null (setting 'textContent')

一見問題がないように見えますが、「Uncaught TypeError: Cannot set property」エラーが発生します。これは、スクリプトがDOMより先に読み込まれ、DOM要素が空であったためです。

scriptタグを他のDOM要素の前に配置した場合にも同じエラーが発生します。

<!DOCTYPE html>
<html>
  <head>
    <title>「Uncaught Typeerror」エラーの解決方法</title>
  </head>
  <body>
    <script src="app.js"></script>
    <h1 id="heading"></h1>
  </body>
</html>

scriptタグはbodyタグ内のDOM要素の前に置かれていますが、この場合もスクリプトがDOMより先に読み込まれます。

この状況での解決方法は、scriptタグをbodyタグを閉じる直前に配置することです。これによって、すべてのDOM要素がスクリプトより先に読み込まれます。

正しい配置例は以下のとおり。

<!DOCTYPE html>
<html>
  <head>
    <title>Uncaught Typeerrorエラーの解決方法</title>
  </head>
  <body>
    <h1 id="heading"></h1>
    <script src="app.js"></script>
  </body>
</html>
let heading = document.getElementById('heading');
heading.textContent = 'This is a heading'

このコードを実行すると、h1要素のtextContentが「This is a heading」に設定され、エラーが発生することはありません。

入力ミス

入力ミスも「Uncaught TypeError: Cannot set property」エラーの原因になります。

JavaScriptでDOM要素を識別するために使用する属性(IDまたはclass)の入力を誤ると、存在しない要素を参照することになり、nullが返されます 。

nullに値を代入しようとすると、このエラーが発生します。

コード例を見てみます。

<!DOCTYPE html>
<html>
  <head>
    <title>「Uncaught Typeerror」エラーの解決方法</title>
  </head>
  <body>
    <h1 id="heading"></h1>
    <script src="app.js"></script>
  </body>
</html>
let heading = document.getElementById('headin');
heading.textContent = 'Hello World!'
//Uncaught TypeError: Cannot set properties of null (setting 'textContent')

このコードのh1タグでは、idheadingとなっています。

また、idを参照していますが、「heading」が「headin」になっており、document.getElementById('heading');が誤ってdocument.getElementById('headin');と書かれています。

エラーの発生を避けるためには、常にDOM要素が正しく参照され、正しい属性を割り当てられているか、入力ミスがないかを確認しましょう。

定義されていないDOM要素へのアクセス

入力ミス同様、存在しないDOM要素にアクセスしようとした場合にもこのエラーが発生します。

以下は、まだマークアップで定義されていないid属性にアクセスしようとする例です。

<!DOCTYPE html>
<html>
  <head>
    <title>「Uncaught Typeerror」エラーの解決方法</title>
  </head>
  <body>
    <h1></h1>
    <script src="app.js"></script>
  </body>
</html>
let heading = document.getElementById('headin');
heading.textContent = 'Hello World!'
//Uncaught TypeError: Cannot set properties of null (setting 'textContent')

このコードは、存在しないDOM要素のtextContentを設定しようとしています。HTMLコードには「heading」のidを持つ要素はないため、nullが返されます。

また、コンソールにheading変数のログを出力すると、nullが返されます。

変数がnullかundefinedであるかを判断する方法

nullまたはundefinedの変数に値を代入すると、ほとんどの場合は「Uncaught TypeError: Cannot set property」エラーを解決できます。

変数がnullまたはundefinedのどちらであるかどうかは、変数と対話する前に判断可能です。これでエラーが解消できるわけではありませんが、エラーの原因は明確になります。

JavaScriptで変数がnullundefinedであるかを判断するには、nullundefinedの値の違いを理解することが重要です。

変数に空または未知の値が代入されると、変数はnullになります(null変数の例は上で見たとおり)。

対するundefinedは、値が代入されていない変数です。

let age;
console.log(age);
// undefined

例えば、上のコードではage変数が宣言されていますが、値は代入されていません。コンソールにログを出力すると、undefinedが返されます。

nullundefinedの違いがわかれば、次はその判別方法です。

この2つの変数は、(緩い)等価演算子(==)を使用して判断することができます。例を見てみましょう。

<!DOCTYPE html>
<html>
  <head>
    <title>「Uncaught Typeerror」エラーの解決方法</title>
  </head>
  <body>
    <h1 id="headin"></h1>
    <script src="app.js"></script>
  </body>
</html>
let heading = document.getElementById('headin');
if (heading == null) {
console.log('Variable is null - cannot assign value to a null variable');
} else {
heading.textContent = 'Hello World!';
}

上のコードは、DOM要素を参照する部分に入力ミスがあります。

また、if文を使ってheading変数の値がnullかどうかをチェックしています(if (heading == null) {...})。

nullを返したため、コンソールに「Variable is null – cannot assign value to a null variable」と表記されます。nullが返されないと、elseブロックのコードが実行されます。

if文にundefinedを含めなかった理由は、JavaScriptではnull == undefinedがであるため。if文で両方のエラーをチェックすることができます。

まとめ

エラーメッセージは時に混乱を招きますが、コードを修正し再度発生することのないよう原因を突き止める手掛かりになります。

エラーを好む人はいませんが、普段扱うプログラミング言語をよりよく理解する機会になります。

コーディングエラーを修正することで、別のプロジェクトで似たようなエラーに遭遇した際に、より状況を把握しやすくなります。今回取り上げた「Uncaught TypeError: Cannot set property」エラーは、Vanilla JS以外でも発生します。

アプリやサイトを開発するには、習得すべきスキルがあります。そしてそのスキルを効率的に使えるようになるには、練習の積み重ねが必要です。Kinstaのホビープランは、コーディング初心者から、自分のプロジェクトを宣伝したり、概念実証のアプリをデプロイしたい経験豊富な開発者まで、テスト環境を必要とするすべての人にお勧めしたいホスティングプランです。今なら初月20ドル分を無料でご利用いただけます。