super とは何か(まずイメージから)
super は、クラスの継承で使う「親クラスへの入り口」です。
具体的には次の2つの役割があります。
- 親クラスの
constructorを呼ぶ - 親クラスのメソッドを呼ぶ
「子どものクラスから、“親のやっていること”を呼び出すためのキーワード」と思ってください。
class Parent {
constructor(name) {
this.name = name;
}
greet() {
console.log(`親の greet: ${this.name}`);
}
}
class Child extends Parent {
constructor(name, age) {
super(name); // 親の constructor を呼ぶ
this.age = age;
}
greet() {
super.greet(); // 親の greet を呼ぶ
console.log(`子の greet: ${this.age} 歳`);
}
}
const c = new Child("Alice", 20);
c.greet();
// 親の greet: Alice
// 子の greet: 20 歳
JavaScriptここが重要です。extends を使うなら、「super はほぼ必ずセットで出てくる」と思ってください。
特に constructor の中の super(...) は、継承クラスでは超重要です。
constructor の中での super(最重要ポイント)
子クラスの constructor では、最初に super(…) が必須
親クラスを継承したクラスで constructor を書くときは、
必ず一番最初に super(...) を呼ばなければいけません。
class Animal {
constructor(name) {
this.name = name;
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name); // 親の constructor(name) を呼ぶ → this.name をセット
this.breed = breed;
}
}
const d = new Dog("ポチ", "柴犬");
console.log(d.name); // ポチ
console.log(d.breed); // 柴犬
JavaScriptもし super(name) を呼ぶ前に this に触ると、エラーになります。
class BadDog extends Animal {
constructor(name, breed) {
// this.breed = breed; // ここで触るとエラー
super(name);
this.breed = breed; // これは OK
}
}
JavaScriptここが重要です。
子クラスの constructor では、「親の準備が終わる前に this を触ってはいけない」というルールがあります。
そのため、「extends しているクラスに constructor を書いたら、まず super(...)」と反射的に書けるようにしておくと楽です。
super(…) の中身は「親 constructor への引数」
super(...) に渡した値は、そのまま親クラスの constructor に渡されます。
class Parent {
constructor(a, b) {
this.a = a;
this.b = b;
}
}
class Child extends Parent {
constructor(a, b, c) {
super(a, b); // Parent の constructor(a, b) を呼ぶ
this.c = c;
}
}
const ch = new Child(1, 2, 3);
console.log(ch); // { a: 1, b: 2, c: 3 }
JavaScript親の constructor の引数が変わったら、それに合わせて super(...) の呼び方も変える必要があります。
親の constructor そのままで良いなら、子に constructor は不要
子クラスで特別な初期化をしたくない場合は、constructor 自体を書かなくてOKです。
class Animal {
constructor(name) {
this.name = name;
}
}
class Dog extends Animal {
// constructor を書かなければ、
// constructor(...args) { super(...args); } があるイメージ
}
const d = new Dog("ポチ");
console.log(d.name); // ポチ
JavaScriptconstructor を書くのは、「親の初期化に加えて、自分独自の初期化が必要なときだけ」です。
メソッドの中での super(親メソッドの呼び出し)
親メソッドを「上書きしつつ、一部だけ変えたい」場合
子クラスで同じ名前のメソッドを定義すると、親のメソッドを「オーバーライド(上書き)」できます。
このとき、親の処理も使いたいなら super.メソッド名() を呼びます。
class Logger {
log(message) {
console.log("LOG:", message);
}
}
class TimestampLogger extends Logger {
log(message) {
const now = new Date().toISOString();
super.log(`${now} - ${message}`); // 親の log を利用
}
}
const logger = new TimestampLogger();
logger.log("Hello");
// LOG: 2025-12-20T...Z - Hello
JavaScriptここが重要です。
「共通の基本処理は親に残し、子では前後に独自の処理を足す」
そのための接着剤として super.method() を使う、という感覚です。
メソッドの中の super の正体
ざっくりいうと、メソッド内での super.xxx() は「親クラスの prototype 上のメソッドを呼んでいる」と考えてOKです。
class Parent {
talk() {
console.log("親です");
}
}
class Child extends Parent {
talk() {
super.talk(); // Parent.prototype.talk.call(this) とほぼ同じ
console.log("子です");
}
}
JavaScriptsuper を通じて親のメソッドを呼ぶときも、this は「今のインスタンス」のままです。
つまり、親メソッドの中からも、子インスタンスのプロパティにアクセスできます。
constructor での super と メソッドでの super の違い
constructor 内の super は「関数呼び出し」
class Parent {
constructor(name) {
this.name = name;
}
}
class Child extends Parent {
constructor(name, age) {
super(name); // 関数呼び出し(親 constructor)
this.age = age;
}
}
JavaScriptここでは super(...) だけで使い、「親 constructor を呼ぶ」特別な構文です。
メソッド内の super は「親のメソッドへの参照」
class Parent {
greet() {
console.log("親の greet");
}
}
class Child extends Parent {
greet() {
super.greet(); // 親メソッドの呼び出し
console.log("子の greet");
}
}
JavaScriptここでは super.greet() のように、「super.メンバー名」の形で使います。
ここが重要です。constructor の中では super(...)(関数呼び出し)、
普通のメソッドの中では super.xxx(...)(親のメソッドやプロパティ参照)
というように、使い方が微妙に違うので混同しないようにしてください。
よくあるつまづきポイントと注意点(ここを押さえると楽)
子クラスの constructor で super を忘れる
一番多いミスがこれです。
class Parent {
constructor() {
this.value = 1;
}
}
class Child extends Parent {
constructor() {
// super(); を忘れると…
this.value = 2; // ここでエラー
}
}
JavaScript「派生クラスの constructor では super() を先に呼ぶ必要があります」
というエラーに出会うことになります。
対策はただひとつ、
「extends したクラスに constructor を書いたら、最初の行に必ず super(...) を書く」。
慣れるまでは、これを機械的ルールにしてしまうのがおすすめです。
親クラスが constructor を持たなくても super() は必要
親クラスが constructor を定義していなくても、
子クラスの constructor では super() を呼ばないといけません。
class Parent {
// constructor は定義していない(=暗黙の constructor() {})
}
class Child extends Parent {
constructor() {
super(); // それでも必須
this.value = 1;
}
}
JavaScript「親に constructor がないから super いらないでしょ?」と思いがちですが、
仕様として「extends しているクラスの constructor では super() が必須」です。
static メソッドからの super の利用(存在だけ知っておけばOK)
少し進んだ使い方として、static メソッドの中でも super が使えます。
class Parent {
static whoAmI() {
console.log("Parent");
}
}
class Child extends Parent {
static whoAmI() {
super.whoAmI(); // Parent.whoAmI()
console.log("Child");
}
}
Child.whoAmI();
// Parent
// Child
JavaScript初心者のうちは、「インスタンスメソッドや constructor で super を使う」ケースをしっかり押さえておけば十分です。
static での super は、「そういうのもある」くらいの理解でOKです。
例題で super の感覚を固める
例1:ユーザーと管理者で共通部分は親にまとめる
class User {
constructor(name) {
this.name = name;
}
describe() {
console.log(`${this.name}(一般ユーザー)`);
}
}
class Admin extends User {
constructor(name, permissions = []) {
super(name); // User の constructor(name) を呼ぶ
this.permissions = permissions;
}
describe() {
super.describe(); // 親の describe も呼ぶ
console.log(`権限: ${this.permissions.join(", ")}`);
}
}
const a = new Admin("Alice", ["READ", "WRITE"]);
a.describe();
// Alice(一般ユーザー)
// 権限: READ, WRITE
JavaScript例2:図形クラスで共通処理+具体クラスの実装
class Shape {
area() {
return 0;
}
describe() {
console.log(`面積: ${this.area()}`);
}
}
class Rectangle extends Shape {
constructor(width, height) {
super(); // 親に特別な初期化はないがルールとして呼ぶ
this.width = width;
this.height = height;
}
area() {
return this.width * this.height;
}
}
const r = new Rectangle(10, 5);
r.describe(); // 面積: 50
JavaScriptdescribe は親に1つだけ定義し、area を子がオーバーライドしています。
ここでは super.describe() を使っていませんが、
「親に共通処理を置いて、子で要点だけ変える」という継承設計の雰囲気が掴めると思います。
例3:ログ出力の前後で親メソッド+追加情報
class Logger {
log(message) {
console.log(message);
}
}
class DebugLogger extends Logger {
log(message) {
const time = new Date().toISOString();
super.log(`[${time}] ${message}`); // 親の log を再利用
}
}
const logger = new DebugLogger();
logger.log("処理開始");
// [2025-12-20T...] 処理開始
JavaScriptまとめ
super の核心は、
「継承関係の中で、“親クラスの constructor やメソッド” を呼び出すためのキーワード」 であることです。
特に大事なのは次のポイントです。
constructor内のsuper(...)は「親の constructor(…) を呼ぶ」特別な構文
子クラスの constructor では、必ず最初に呼ばなければならない- メソッド内の
super.method(...)は「親クラスの同名メソッドを呼ぶ」
親の処理+子の追加処理、という形を作るのに便利 - 親の constructor をそのまま使うだけなら、子クラスに constructor は書かなくて良い
extendsを使うなら、「super はセットで覚える」くらいの重要な存在
まずは、親クラスと子クラスを自分で1セット作ってみて、
「親に共通処理」「子で差分」「子の constructor で super」を何度か手で書いてみてください。
super が“必須な場面”と“便利な場面”が、だんだん感覚として分かってきます。
