1日目のゴールと作るもののイメージ
1日目のテーマは
「class を使って、“それっぽいオブジェクト”を自分で設計できるようになること」です。
キーワードはこの3つです。
class
カプセル化(中身を隠す・守る)
責務分離(役割を分ける)
いきなり難しいアプリにはしません。
まずは「シンプルなメモ」を扱うクラスを作りながら、
オブジェクト指向の“感覚”をつかんでいきます。
class とは何かを直感でつかむ
「設計図」と「実物」というイメージ
JavaScript の class は、ざっくり言うと
「オブジェクトを作るための設計図」
です。
設計図(class)から、
実物(インスタンス)を何個でも作れます。
まずは、超シンプルな例から。
class Memo {
constructor(text) {
this.text = text;
}
}
const m1 = new Memo("買い物に行く");
const m2 = new Memo("勉強する");
console.log(m1.text); // 買い物に行く
console.log(m2.text); // 勉強する
JavaScriptここでやっていることを言葉で整理すると、
Memo という「メモ用の設計図」を定義する。
constructor で「作るときに必要な情報」(text)を受け取る。
new Memo(…) で「実物のメモ」を作る。
この「設計図 → 実物」の感覚が、class の出発点です。
constructor と this の役割をちゃんと理解する
constructor は「生まれた瞬間に呼ばれる関数」
constructor は、そのクラスから new されたときに
自動で呼ばれる特別なメソッドです。
class Memo {
constructor(text) {
console.log("Memo が 1 つ生まれました");
this.text = text;
}
}
JavaScriptnew Memo("テスト") とすると、
「Memo が 1 つ生まれました」
というログが出て、this.text に "テスト" が入ります。
this は「今まさに作っている(または扱っている)その1個」
this は、「今操作しているそのインスタンス自身」を指します。
class Memo {
constructor(text) {
this.text = text;
}
show() {
console.log("メモ:", this.text);
}
}
const m = new Memo("ご飯を作る");
m.show(); // メモ: ご飯を作る
JavaScriptここでの this.text は、
constructor の中でも
show メソッドの中でも
「同じメモオブジェクトの text」を指しています。
重要ポイント:
this は「クラス全体」ではなく、
「その1個、その瞬間のインスタンス」を指す。
これが分かると、
「同じ設計図から作ったのに、中身が違うオブジェクト」を
自然に扱えるようになります。
カプセル化とは何か(“中身を守る”という発想)
なんでも外から触れると、すぐ壊れる
さっきの Memo クラスは、こうでした。
class Memo {
constructor(text) {
this.text = text;
}
}
JavaScriptこれだと、外からこう書けてしまいます。
const m = new Memo("大事なメモ");
m.text = 12345; // 文字列じゃないものを入れてしまえる
JavaScript「text は文字列であってほしい」のに、
誰でも好き勝手に書き換えられる状態です。
これだと、アプリが大きくなったときに
「どこでおかしくなったのか」が追いづらくなります。
そこで出てくるのが「カプセル化」です。
カプセル化=「中身を直接触らせず、窓口を用意する」
JavaScript では、# を使って「プライベートフィールド」を作れます。
class Memo {
#text; // 外から直接触れない
constructor(text) {
this.#text = text;
}
getText() {
return this.#text;
}
setText(newText) {
if (typeof newText !== "string") {
console.warn("文字列以外はセットできません");
return;
}
this.#text = newText;
}
}
const m = new Memo("最初のメモ");
console.log(m.getText()); // 最初のメモ
m.setText("書き換えたメモ");
console.log(m.getText()); // 書き換えたメモ
m.setText(123); // 警告が出て、値は変わらない
JavaScriptここで起きていることを整理すると、
#text はクラスの外からは見えない・触れない。
代わりに、getText / setText という「窓口メソッド」を用意する。
setText の中で「文字列かどうか」をチェックしている。
つまり、
「中身を守るために、直接触らせず、ルール付きの入り口を作る」
これがカプセル化です。
責務分離とは何か(“1人に何役もやらせない”)
なんでもかんでも 1 クラスに詰め込むと地獄になる
例えば、こんなクラスを想像してみてください。
メモの内容を持つ
メモの一覧を管理する
メモを検索する
メモを削除する
画面に表示する
これを全部 1 クラスに詰め込むと、
そのクラスは「なんでも屋」になってしまいます。
変更に弱く、テストしづらく、
読んでいても「結局このクラス、何者?」となりがちです。
そこで出てくるのが「責務分離」です。
責務分離=「役割ごとにクラスを分ける」
例えば、こう分けられます。
Memo:1つのメモそのものを表すクラス
MemoList:複数のメモを管理するクラス
まずは Memo をシンプルに保ちます。
class Memo {
#text;
constructor(text) {
this.#text = text;
}
getText() {
return this.#text;
}
setText(newText) {
if (typeof newText !== "string") {
console.warn("文字列以外はセットできません");
return;
}
this.#text = newText;
}
}
JavaScript次に、MemoList を作ります。
class MemoList {
#memos;
constructor() {
this.#memos = [];
}
add(text) {
const memo = new Memo(text);
this.#memos.push(memo);
}
getAll() {
return this.#memos;
}
findByKeyword(keyword) {
return this.#memos.filter(memo => memo.getText().includes(keyword));
}
}
JavaScriptここでの役割分担はこうです。
Memo:1つのメモの中身を守る・扱う。
MemoList:メモの集まりを管理する(追加・検索など)。
重要ポイント:
「1クラス=1つの責任」に近づけるほど、
コードは読みやすく、変更しやすくなります。
小さな例題:コンソールで動く簡単なメモ管理
クラスを使わない場合との違いを感じる
クラスを使わないと、こうなりがちです。
const memos = [];
function addMemo(text) {
memos.push(text);
}
function showMemos() {
memos.forEach((m, i) => {
console.log(i + 1, m);
});
}
JavaScriptこれはこれで動きますが、
メモに「作成日時」や「重要フラグ」などを足したくなったとき、
配列の中身がどんどん複雑になっていきます。
クラスを使うと、こう書けます。
class Memo {
#text;
#createdAt;
constructor(text) {
this.#text = text;
this.#createdAt = new Date();
}
getText() {
return this.#text;
}
getCreatedAt() {
return this.#createdAt;
}
}
class MemoList {
#memos;
constructor() {
this.#memos = [];
}
add(text) {
const memo = new Memo(text);
this.#memos.push(memo);
}
showAll() {
this.#memos.forEach((memo, index) => {
console.log(
index + 1,
memo.getText(),
"(" + memo.getCreatedAt().toLocaleString() + ")"
);
});
}
}
const list = new MemoList();
list.add("牛乳を買う");
list.add("本を読む");
list.showAll();
JavaScriptここで感じてほしいのは、
「メモに何か属性を足したくなったとき、Memo クラスだけを見ればいい」
という安心感です。
配列の中身が「ただの文字列」ではなく、
「ちゃんとしたメモオブジェクト」になっていることで、
設計がスッキリしていきます。
1日目でいちばん深く理解してほしいこと
今日のキーワードを、感覚レベルでまとめます。
class:
「オブジェクトの設計図」。
constructor で「生まれた瞬間の初期化」を書く。
this は「その1個の実物」を指す。
カプセル化:
「中身を直接触らせず、ルール付きの窓口を用意する」。
JavaScript では #フィールド と getter / setter で実現できる。
責務分離:
「1クラスに何役もやらせず、役割ごとにクラスを分ける」。
Memo は「1つのメモ」、MemoList は「メモの集まり」。
1日目は、
「クラスってそういう“考え方の箱”なんだな」
という感覚が持てていれば十分です。
次のステップでは、この Memo / MemoList をベースにして、
「メソッドを増やす」
「状態を変える」
「画面(DOM)とクラスをどうつなぐか」
といったところに進んでいきます。
そのとき、今日の「カプセル化」と「責務分離」が、
かなり効いてきます。


