1. 人気と通常が混ざる
  2. 空の配列
  3. ちょうど 100 回は人気
  4. 99 回は通常
  5. 3 件すべて人気
コース一覧
モダンJavaScript:データ処理とコード設計
多態と static

モダンJavaScript:データ処理とコード設計

配列の map・filter・reduce・sort、クロージャと高階関数、オブジェクトとクラス、エラー設計、正規表現を学ぶ全 36 レッスン(665 分)のコースです。ローカルの作品データを題材に、表示とデータを分け、絞り込み・並び替え・入力検証までを組み立てます。Promise、fetch、API 通信、モジュールは次のコースで扱います。

1
土台をそろえる
01. このコースで育てるもの15分
02. strict mode が先に教えてくれる間違い15分
03. 表示とデータを切り分ける20分
04. 第1章まとめクイズ10分
2
配列をパイプラインで扱う
01. map で形を変える20分
02. filter と find で絞り込む20分
03. reduce でひとつにまとめる20分
04. sort と比較関数20分
05. 分類してまとめる groupBy20分
06. つなげて組み立てる20分
07. つくる 作品一覧の絞り込みと並び替え30分
08. 第2章まとめクイズ10分
3
関数を道具にする
01. クロージャで状態を閉じ込める20分
02. 設定を覚えた関数をつくる20分
03. 関数を返す関数20分
04. 副作用のない関数20分
05. 第3章まとめクイズ10分
4
オブジェクトを扱いきる
01. 分割代入で必要な値だけ取り出す20分
02. スプレッドとレストで組み替える20分
03. keys と values と entries20分
04. ビット演算でフラグをまとめる20分
05. 第4章まとめクイズ10分
5
クラスで型をつくる
01. クラスとインスタンス20分
02. private フィールドとアクセサ20分
03. 継承と super20分
04. 多態と static20分
05. つくる 作品コレクションをクラスにする30分
06. 第5章まとめクイズ10分
6
エラーを設計する
01. try catch finally20分
02. 自分でエラーを投げる20分
03. 失敗を画面に出す25分
04. 第6章まとめクイズ10分
7
正規表現
01. 正規表現のきほん20分
02. 入力を検証する20分
03. 置換とキャプチャ20分
04. 第7章まとめクイズ10分

多態と static

クラスに付く値と実体ごとの値
解説

このレッスンで分かること

  • 同じ名前のメソッドを種類ごとに用意すると、使う側から if が消えます
  • static を付けたものはインスタンスではなくクラスに付き、値がそのまま残り続けます

呼ぶ側の if が、種類の数だけ増える

前の回で、種類ごとにクラスを分けました。分けたあと、使う側がこう書いていると苦しくなります。

JavaScript

const lines = notes.map((note) => { if (note instanceof PinnedNote) { return "重要 " + note.topic + " " + note.minutes + " 分"; } return note.topic + " " + note.minutes + " 分"; });

種類が 3 つになれば分岐が 3 本並びます。しかも同じ分岐を、一覧の描画、件数の集計、並び替えと、場所ごとに書き写すことになります。1 か所を直し忘れると、そこだけ古い表示が残ります。

同じ名前のメソッドを両方のクラスに持たせておけば、分岐はクラスの側に 1 回書くだけで済みます。

JavaScript

const lines = notes.map((note) => note.render());

どちらの render が動くかは、そのインスタンスがどのクラスから作られたかで自動的に決まります。呼ぶ側は種類を知らなくてよくなります。

解説

効くのは、メソッド名が完全に同じで、引数と戻り値の形もそろっているときだけです。片方が文字列を返し、もう片方がオブジェクトを返すなら、結局呼ぶ側で分岐することになります。名前だけそろえても意味がありません。

static はインスタンスではなくクラスに付く

ここまでのメソッドは new で作ったインスタンスから呼ぶものでした。static を付けると、クラス名から直接呼ぶものになります。

JavaScript

class Comment { static total = 0; constructor(body) { this.body = body; Comment.total += 1; } static countLabel() { return `これまでに ${Comment.total} 件`; } } new Comment("はじめまして"); new Comment("参考になりました"); console.log(Comment.total); // 2 console.log(Comment.countLabel()); // これまでに 2 件
書き方誰に付くか呼び方
render() {}インスタンスnote.render()
static countLabel() {}クラスComment.countLabel()
static total = 0クラスComment.total

total は Comment に 1 つだけあります。comment.total と書いても undefined です。インスタンスからは見えません。

static のメソッドは new より前に呼べるので、「どのクラスで作るか」の判断をクラス自身に持たせる窓口にもできます。呼ぶ側は子クラスの名前を知らずに済み、あとで種類が増えても直すのはその窓口の中だけです。

static に置いた数は、次の呼び出しにも残る

static のフィールドは、プログラムが動いている間ずっと生き続けます。同じ関数を 2 回呼ぶと、2 回目は前回に増えた分を引きずります。

JavaScript

console.log(Comment.total); // 2 new Comment("また来ました"); console.log(Comment.total); // 3

第3章で、何回呼んでも同じ結果になる関数のことを学びました。static を使うとその性質は簡単に崩れます。数え直したいなら、数える処理の先頭で 0 に戻すと決めておきます。戻す場所を末尾に置くと、途中で return したときに素通りします。

解説

static に持たせてよいのは、クラス全体で 1 つと決まっているものだけです。作った件数や既定の設定値がそれにあたります。個々のインスタンスに関わる値を置くと、あとから作ったほうに上書きされます。

よくある間違い

  • インスタンスから static を呼ぶ — comment.countLabel() は TypeError です。static はクラスに付いているので、クラス名から呼びます
  • static の中の this をインスタンスのつもりで使う — static の this はクラス自身です。this.body と書いても undefined にしかなりません
  • 上書きしたつもりでメソッド名を間違える — render を rendar と書いても、その場ではエラーになりません。子のインスタンスで呼ぶと親のほうが静かに動き、印の付かない行だけが混ざります

要件

  1. class Work は static created を 0 から始め、constructor が呼ばれるたびに Work.created を 1 増やす。format() は タイトル N 回 を返す
  2. static from(record) は record.views が 100 以上なら PopularWork、それ以外なら Work のインスタンスを返す
  3. class PopularWork extends Work は format() を上書きし、super.format() の後ろに半角スペースと 人気 を足した文字列を返す
  4. function buildWorkReport(records) を定義する。先頭で Work.created を 0 に戻してから Work.from で作り、{ lines, created } を返す

入出力例

buildWorkReport([{"title":"プロフィールサイト","views":120},{"title":"学習ログ","views":8}]) → {"created":2,"lines":["プロフィールサイト 120 回 人気","学習ログ 8 回"]} buildWorkReport([]) → {"created":0,"lines":[]} buildWorkReport([{"title":"作品ギャラリー","views":100}]) → {"created":1,"lines":["作品ギャラリー 100 回 人気"]} buildWorkReport([{"title":"自己紹介カード","views":99}]) → {"created":1,"lines":["自己紹介カード 99 回"]} buildWorkReport([{"title":"プロフィールサイト","views":120},{"title":"作品ギャラリー","views":200},{"title":"スキル一覧の表","views":300}]) → {"created":3,"lines":["プロフィールサイト 120 回 人気","作品ギャラリー 200 回 人気","スキル一覧の表 300 回 人気"]}

ヒント

static from の中で PopularWork を使いますが、PopularWork の宣言は下に書いてあって構いません。from が動くのは両方が読み込まれたあとです

PopularWork には constructor を書きません。書かなければ親の constructor がそのまま動き、created も増えます

buildWorkReport の先頭で Work.created = 0 を書き忘れると、2 回目以降の呼び出しで件数が積み上がります

生田 陸人
監修生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
編集 ゆめさく編集部·公開 2026/03/27·更新 2026/08/26

関連レッスン

  • つくる 作品コレクションをクラスにする

    第5章で学んだ class と # と extends と static を全部使い、作品 1 件の Work と、その集まりの WorkCollection にまとめます。

  • 第5章まとめクイズ

    class と constructor、# の private フィールド、extends と super、static の 4 つを、コードを読んで結果を答える形で確かめます。

  • try catch finally

    失敗するかもしれない処理を try で囲み、catch で受け止めて finally で後始末する書き方を身につけます。

  • 正規表現のきほん

    文字列を文字ではなく形で探す正規表現を導入します。文字クラスと量指定子を読めるようにして、match で当たった部分を取り出せるようになります。

このレッスンに出てくる用語

意味があいまいなまま進んだ語は、ここから読み直せます。

  • メソッドクラスに属する関数
  • インスタンスクラスから生成された実体
  • クラスデータと振る舞いを束ねる単位
  • 引数位置引数=順番で渡す。
  • 戻り値呼び出し元への返答を表す点線矢印
  • オブジェクトキーと値のペアで構造を作るデータ
  • 判断YES/NO 分岐を表す菱形
  • フィールドクラスが持つデータ
main.js
学習モード
エディタを読み込んでいます

メモ

多態と static

⌘S で保存