JavaScriptのプロトタイプとクラス
プロトタイプとは
- プロトタイプは、JavaScriptオブジェクトが互いに機能を継承するための仕組みです
- すべての関数は prototypeオブジェクト を持つことができ、作成したオブジェクトはこのプロトタイプ経由でメソッドを共有できます
ファクトリ関数
- 関数を使ってオブジェクトを作る方法
- デメリット:同じメソッドがオブジェクトごとに作られるため、メモリ効率が悪い
function createColor(r, g, b) {
return {
r,
g,
b,
rgb: function() {
return `rgb(${r}, ${g}, ${b})`;
},
};
}
const color1 = createColor(40, 50, 60);
const color2 = createColor(255, 100, 50);
コンストラクタ関数とプロトタイプ
-
コンストラクタ関数は
newを使ってオブジェクトを作成する方法 - メソッドを
prototypeに置くことで、全インスタンスで共有できる
function Color(r, g, b) {
this.r = r;
this.g = g;
this.b = b;
}
// prototypeにメソッドを定義
Color.prototype.rgb = function () {
return `rgb(${this.r}, ${this.g}, ${this.b})`;
};
const color1 = new Color(40, 50, 60);
console.log(color1.rgb()); // "rgb(40, 50, 60)"
new 演算子の仕組み
- 空のオブジェクトを作る
- 新しいオブジェクトのプロトタイプをコンストラクタの
prototypeにリンク -
thisに新しいオブジェクトを割り当て - 関数がオブジェクトを返さなければ
thisを返す
const color2 = new Color(40, 255, 60);
JavaScriptのクラス(ES6以降)
- クラス構文で、コンストラクタ関数とプロトタイプをよりシンプルに書けます
class Color {
constructor(r, g, b, name) {
this.r = r;
this.g = g;
this.b = b;
this.name = name;
}
rgb() {
return `rgb(${this.r}, ${this.g}, ${this.b})`;
}
hex() {
return "#" + ((1 << 24) + (this.r << 16) + (this.g << 8) + this.b)
.toString(16)
.slice(1);
}
}
const red = new Color(255, 67, 89, "tomato");
const white = new Color(255, 255, 255, "white");
console.log(red.rgb()); // "rgb(255, 67, 89)"
console.log(red.hex()); // "#ff4359"
継承(extends と super)
- クラス同士で継承する場合は
extendsとsuperを使用
class Pet {
constructor(name, age) {
this.name = name;
this.age = age;
}
eat() {
return `${this.name}がご飯を食べている`;
}
}
class Cat extends Pet {
constructor(name, age, jumpHeight = 5) {
super(name, age); // 親クラスのconstructorを呼ぶ
this.jumpHeight = jumpHeight;
}
meow() {
return "にゃー!!!";
}
}
class Dog extends Pet {
bark() {
return "わんわん";
}
// メソッドをオーバーライド
eat() {
return `${this.name}がご飯を食い散らかしている`;
}
}
const myCat = new Cat("タマ", 3);
console.log(myCat.eat()); // "タマがご飯を食べている"
console.log(myCat.meow()); // "にゃー!!!"
const myDog = new Dog("ポチ", 5);
console.log(myDog.eat()); // "ポチがご飯を食い散らかしている"
console.log(myDog.bark()); // "わんわん"
💡 ポイント
- プロトタイプを理解すると、クラスも「メソッドを共有する仕組み」として自然に理解できる
-
extendsとsuperで親クラスの機能をそのまま使いながら、必要に応じてオーバーライドも可能