JavaScriptにおける「オブジェクト指向プログラミング(OOP)」は、非常に重要かつ基本的な概念である。この記事では、JavaScriptにおけるオブジェクトの構造、作成方法、プロトタイプ継承、クラスの定義、エンカプスレーション、ポリモーフィズム、抽象化といった要素を完全かつ包括的に解説する。現代のフロントエンドやバックエンド開発では、React、Node.js、Vue.jsなどの技術スタックでOOPの理解が欠かせない。
オブジェクトの基本構造
JavaScriptにおけるオブジェクトとは、キー(プロパティ名)と値のペアの集合である。JavaScriptでは、オブジェクトはデータと振る舞い(メソッド)を一つにまとめた構造体として機能する。
javascriptconst person = {
name: "田中",
age: 30,
greet: function() {
console.log("こんにちは、私は" + this.name + "です。");
}
};
person.greet(); // 出力: こんにちは、私は田中です。
オブジェクトのプロパティには文字列、数値、配列、関数、他のオブジェクトなど様々な型が利用可能である。
オブジェクトの生成方法
オブジェクトは以下のような方法で生成できる:
1. リテラル構文(最も一般的)
javascriptlet car = {
make: "トヨタ",
model: "カローラ"
};
2. Objectコンストラクタ
javascriptlet car = new Object();
car.make = "トヨタ";
car.model = "プリウス";
3. コンストラクタ関数による定義
javascriptfunction Car(make, model) {
this.make = make;
this.model = model;
}
let car1 = new Car("トヨタ", "アクア");
4. クラス構文(ES6以降)
javascriptclass Car {
constructor(make, model) {
this.make = make;
this.model = model;
}
info() {
return `${this.make} の ${this.model}`;
}
}
const car = new Car("ホンダ", "フィット");
console.log(car.info());
メソッドと this のキーワード
this は、メソッドが呼び出されたオブジェクトを参照する。
javascriptconst book = {
title: "JavaScript入門",
showTitle: function() {
console.log(this.title);
}
};
book.showTitle(); // 出力: JavaScript入門
関数の外で使用された this は、通常はグローバルオブジェクト(ブラウザでは window)を参照するが、strict mode では undefined になるため注意が必要である。
プロトタイプと継承
JavaScriptはプロトタイプベースの言語であり、すべてのオブジェクトはプロトタイプチェーンを持つ。
javascriptfunction Animal(name) {
this.name = name;
}
Animal.prototype.speak = function() {
console.log(`${this.name} が鳴いています。`);
};
const dog = new Animal("ポチ");
dog.speak(); // 出力: ポチ が鳴いています。
プロトタイプチェーンの仕組み
textdog → Animal.prototype → Object.prototype → null
このチェーンにより、オブジェクトは自分のプロパティが存在しない場合、上位のプロトタイプに検索を委ねる。
クラスベースの継承(ES6)
javascriptclass Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} が鳴いています。`);
}
}
class Dog extends Animal {
speak() {
console.log(`${this.name} がワンワンと鳴いています。`);
}
}
const myDog = new Dog("コロ");
myDog.speak(); // 出力: コロ がワンワンと鳴いています。
superキーワードの使用
親クラスのコンストラクタやメソッドを参照するために super を使う。
javascriptclass Cat extends Animal {
constructor(name, color) {
super(name);
this.color = color;
}
describe() {
console.log(`${this.color}色の猫、${this.name}`);
}
}
エンカプスレーション(カプセル化)
エンカプスレーションとは、内部の状態を隠蔽し、外部からのアクセスを制御する設計思想である。ES2022以降、プライベートフィールドに # を使うことで本格的なカプセル化が可能になった。
javascriptclass BankAccount {
#balance = 0;
deposit(amount) {
if (amount > 0) {
this.#balance += amount;
}
}
getBalance() {
return this.#balance;
}
}
const account = new BankAccount();
account.deposit(10000);
console.log(account.getBalance()); // 出力: 10000
ポリモーフィズム(多態性)
同じインターフェースで異なるクラスが異なる動作を実装できる。
javascriptclass Bird {
fly() {
console.log("鳥が飛びます");
}
}
class Airplane {
fly() {
console.log("飛行機が飛びます");
}
}
function startFlying(entity) {
entity.fly();
}
const sparrow = new Bird();
const jet = new Airplane();
startFlying(sparrow); // 鳥が飛びます
startFlying(jet); // 飛行機が飛びます
抽象化
JavaScriptには正式な抽象クラスは存在しないが、設計として抽象的な動作を定義し、それを実装に委ねることができる。
javascriptclass Shape {
area() {
throw new Error("このメソッドはオーバーライドされる必要があります");
}
}
class Circle extends Shape {
constructor(radius) {
super();
this.radius = radius;
}
area() {
return Math.PI * this.radius * this.radius;
}
}
Object関連メソッド
| メソッド名 | 説明 |
|---|---|
Object.keys(obj) |
プロパティ名の配列を返す |
Object.values(obj) |
プロパティ値の配列を返す |
Object.entries(obj) |
キーと値のペアを配列として返す |
Object.assign(target, source) |
オブジェクトをマージする |
Object.freeze(obj) |
オブジェクトを凍結し、変更不能にする |
Object.seal(obj) |
追加と削除を禁止するが、既存のプロパティの変更は可能 |
javascriptconst user = {
name: "山田",
age: 28
};
Object.freeze(user);
user.age = 30; // 効果なし
console.log(user.age); // 出力: 28
JSONとの関係
JavaScriptのオブジェクトはJSON(JavaScript Object Notation)との相互変換が可能であり、データ通信に多用される。
javascriptconst obj = { name: "佐藤", age: 40 };
const jsonStr = JSON.stringify(obj); // JSON文字列へ変換
const newObj = JSON.parse(jsonStr); // オブジェクトへ戻す
今後の展望:オブジェクト指向とJavaScriptの進化
JavaScriptのオブジェクト指向機能は、年々進化している。プライベートフィールド、デコレーター、クラスの静的ブロック、Mixinパターンの普及など、より柔軟で安全な設計が可能になっている。TypeScriptとの併用により、型安全性も向上するため、より本格的なOOP開発が実現されている。
まとめ
JavaScriptにおけるオブジェクト指向プログラミングは、柔軟かつ強力なプログラミングパラダイムである。以下の要素が重要である:
-
オブジェクトの構築とプロパティの操作
-
プロトタイプ継承とクラスベース継承の理解
-
エンカプスレーションと情報隠蔽
-
ポリモーフィズムと抽象化の応用
-
JSONとの連携によるデータ表現
-
最新のES仕様とTypeScriptによる拡張性
これらを適切に理解し応用することで、JavaScriptでの大規模開発や保守性の高いアプリケーションの構築が可能となる。
参考文献
-
Mozilla Developer Network (MDN): https://developer.mozilla.org/ja/
-
ECMAScript仕様: https://tc39.es/
-
Axel Rauschmayer. Speaking JavaScript (O’Reilly, 2014)
-
Kyle Simpson. You Don’t Know JS シリーズ(2020年改訂版)
