Code Fix

上級

インスタンス全体で共有したい値をstaticにし忘れる

クラスのインスタンスをまたいで値を共有したい場合はstaticフィールドが必要です。staticを付け忘れると、その値はクラス自身ではなく各インスタンスに独立して属するため、期待した共有ができません。

なぜエラーが出ないのか

出力: NaN
(エラーなし)
JavaScriptは何も報告しません。文法として正しいためです
出力: NaN
実際の挙動 — 期待した結果と食い違っている箇所
見つけ方
エラーが出ないので、出力を目で確かめるか、コードを目で追うしかありません。この種の誤りが最も発見が遅れます

このエラーが出る典型パターン

パターン1

 1  class Widget {
 2           count = 0;
         ^
 3    constructor() {
 4      Widget.count++;
 5    }
 6  }
 7  new Widget();
 8  new Widget();
 9  new Widget();
10  console.log(Widget.count);
出力: NaN期待: 3 (エラーにはなりません)

staticを付けないcountはインスタンスごとのフィールドになり、Widget.countという静的プロパティは存在しません。undefined++の結果であるNaNがWidget.countに代入され続けます。

直し方: (空)static にします。

この問題を解いてみる →

広告
広告スロット(未設定)

パターン2

 1  class Ticket {
 2           nextId = 1;
         ^
 3    constructor() {
 4      this.id = Ticket.nextId++;
 5    }
 6  }
 7  const t1 = new Ticket();
 8  const t2 = new Ticket();
 9  const t3 = new Ticket();
10  console.log(t3.id);
出力: NaN期待: 3 (エラーにはなりません)

nextIdをstaticにしないと、Ticket.nextIdはクラス自身のプロパティとして存在せず、undefined++でNaNになってしまいます。

直し方: (空)static にします。

この問題を解いてみる →

パターン3

 1  class Logger {
 2           history = [];
         ^
 3    static log(msg) {
 4      Logger.history.push(msg);
 5    }
 6  }
 7  Logger.log("a");
 8  Logger.log("b");
 9  console.log(Logger.history.length);
main.js:4 Logger.history.push(msg); ^ TypeError: Cannot read properties of undefined (reading 'push')

historyをstaticにしないと、Logger.historyはクラス自身には存在せずundefinedのままです。pushを呼ぼうとした瞬間にエラーになります。

直し方: (空)static にします。

この問題を解いてみる →

よくある誤解

「クラスに書いたフィールドはクラス全体で1つのはず」という思い込みは誤りです。staticを付けない限り、フィールドはnewするたびに新しく作られる、インスタンスごとに独立した値になります。

まとめ

インスタンス全体で共有したい値をstaticにし忘れるは上級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)