静的メソッドとは何か(まずイメージから)
静的メソッド(static メソッド)は、
「インスタンスではなく“クラスそのもの”に属するメソッド」 です。
普通のメソッドはこう呼びます。
const user = new User("Alice");
user.greet(); // インスタンスから呼ぶ
JavaScript静的メソッドはこう呼びます。
User.fromJson("..."); // クラス名から直接呼ぶ
Math.max(1, 2, 3); // これも静的メソッドの一種
JavaScriptMath.max には「Math のインスタンス」はいりませんよね。
「個々のインスタンスに紐づかない、“クラスに関する便利な処理”」をまとめる場所
それが静的メソッドです。
基本構文と普通のメソッドとの違い
どう書くのか
class の中で、メソッドの前に static を付けるだけです。
class User {
constructor(name) {
this.name = name;
}
greet() { // インスタンスメソッド
console.log(`Hi, ${this.name}`);
}
static createGuest() { // 静的メソッド
return new User("Guest");
}
}
const u1 = new User("Alice");
u1.greet(); // インスタンスから呼ぶ
const guest = User.createGuest(); // クラスから呼ぶ
guest.greet(); // 作られたインスタンスを使う
JavaScriptここが重要です。
インスタンスメソッド:u.greet() のようにインスタンスから呼ぶ
静的メソッド:User.createGuest() のようにクラス名から呼ぶ
「使い方」がそもそも違うと押さえておいてください。
this の中身が全然違う
インスタンスメソッド内の this は「そのインスタンス」ですが、
静的メソッド内の this は「クラス(その関数自体)」を指します。
class Example {
constructor() {
this.value = 123;
}
showInstance() {
console.log("instance this.value:", this.value);
}
static showStatic() {
console.log("static this:", this);
}
}
const e = new Example();
e.showInstance(); // instance this.value: 123
Example.showStatic(); // static this: [class Example] みたいな形
JavaScript静的メソッドでは「特定のインスタンス」ではなく「クラス全体」に関する情報・処理を扱う、
と意識すると this の違いに納得がいきます。
どんなときに静的メソッドを使うのか(考え方)
インスタンスを「作るための工場メソッド」
よくある使い方は、インスタンス生成の便利関数です。
class User {
constructor(name, admin = false) {
this.name = name;
this.admin = admin;
}
describe() {
console.log(`${this.name} (${this.admin ? "管理者" : "一般"})`);
}
static createAdmin(name) {
return new User(name, true);
}
static createGuest() {
return new User("Guest", false);
}
}
const u1 = User.createAdmin("Alice");
const u2 = User.createGuest();
u1.describe(); // Alice (管理者)
u2.describe(); // Guest (一般)
JavaScriptここが重要です。
「よく使うインスタンスの作り方」を静的メソッドとして名前付きで用意しておくと、
使う側が new User(...) の細かいルールを知らなくても、安全にインスタンスを作れます。
インスタンスに依存しない「ユーティリティ的な処理」
個々のユーザーには関係なく、「ユーザーという概念に関する処理」を書きたいときにも使えます。
class PasswordUtil {
static isStrong(password) {
return password.length >= 8 && /[0-9]/.test(password);
}
}
console.log(PasswordUtil.isStrong("abc")); // false
console.log(PasswordUtil.isStrong("abc12345"));// true
JavaScriptわざわざ new PasswordUtil() としてインスタンスを作る必要はないですよね。
このような「状態を持たない、ただの計算・チェック」系は静的メソッドと相性が良いです。
そのクラスに属する「共通の情報・定数」を扱う
例えば、インスタンス数をカウントする、バージョン情報を返す、など。
class Counter {
static count = 0; // クラス全体で共有するフィールド
constructor() {
this.id = ++Counter.count;
}
static getTotalCount() {
return Counter.count;
}
}
const c1 = new Counter();
const c2 = new Counter();
console.log(c1.id); // 1
console.log(c2.id); // 2
console.log(Counter.getTotalCount()); // 2
JavaScriptここが重要です。
「個々のインスタンスの状態」ではなく、「クラス全体で共有する状態」を扱う場所として静的メソッド(+静的フィールド)が使える
と考えると、使いどころが見えてきます。
静的メソッドとインスタンスメソッドをどう使い分けるか
判断基準は「その処理はインスタンスに依存するか?」
例えば User クラスで考えます。
class User {
constructor(name, email) {
this.name = name;
this.email = email;
}
sendEmail(subject, body) {
// このユーザーの email に送る
console.log(`To: ${this.email}, ${subject}`);
}
static validateEmail(email) {
return email.includes("@");
}
}
JavaScriptsendEmail は 特定のユーザーの email アドレス に送る処理なので、インスタンスメソッド。validateEmail は 文字列(email)が正しい形かどうか を判定するだけなので、インスタンスは不要 → 静的メソッド。
ここが重要です。
「this(インスタンスの状態)が必要な処理」→ インスタンスメソッド
「this が不要な処理」→ 静的メソッド
というシンプルな判断でほとんどの場合うまくいきます。
「全部静的メソッドでいいじゃん?」と思ったとき
確かに、クラスの中に全部 static で書くこともできます。
ただそれは、クラスというより「名前空間付きの関数集」になってしまいます。
インスタンスメソッドを使うと、
thisを通じてオブジェクトの状態を持てる- 「状態と振る舞い」がセットになって、扱いやすくなる
静的メソッドは、
- インスタンスに紐付かない処理を、クラスの“周辺”にまとめておける
という役割分担です。
両者を意識的に使い分けることで、クラス設計がぐっと読みやすくなります。
継承と静的メソッド(super との関係も)
静的メソッドも継承される
親クラスの静的メソッドは、子クラスからも使えます。
class Animal {
static isAnimal(obj) {
return obj instanceof Animal;
}
}
class Dog extends Animal {}
const d = new Dog();
console.log(Animal.isAnimal(d)); // true
console.log(Dog.isAnimal(d)); // true(Dog からも呼べる)
JavaScriptDog は Animal を継承しているので、静的メソッドも引き継ぎます。
親の静的メソッドを上書き・拡張する
子クラスで同じ名前の静的メソッドを定義すると、オーバーライドできます。
その際に super も使えます。
class Animal {
static describeClass() {
console.log("Animal クラス");
}
}
class Dog extends Animal {
static describeClass() {
super.describeClass(); // 親の静的メソッド
console.log("Dog クラス");
}
}
Dog.describeClass();
// Animal クラス
// Dog クラス
JavaScriptここが重要です。
インスタンスメソッドの継承と同じように、静的メソッドも「継承される」「オーバーライドできる」「super で親を呼べる」
という点は頭に入れておくと、他人のコードが読みやすくなります。
よくある勘違いと注意点(ここを押さえておくと楽)
静的メソッドはインスタンスから呼べない
これ、最初によくやります。
class User {
static hello() {
console.log("Hello");
}
}
const u = new User();
u.hello(); // TypeError: u.hello is not a function
User.hello(); // 正しい呼び方
JavaScript静的メソッドは インスタンスには存在しません。
あくまで「クラスオブジェクト(User)にぶら下がっている関数」です。
静的メソッドの中でインスタンスの this は使えない
静的メソッドの中の this は「クラス」なので、this.name のようなインスタンスプロパティはありません。
class User {
constructor(name) {
this.name = name;
}
static bad() {
console.log(this.name); // ここでの this はクラス(User)、インスタンスではない
}
}
const u = new User("Alice");
User.bad(); // undefined(期待した結果にならない)
JavaScript「インスタンスのプロパティを使いたいなら、それは静的メソッドではない」
と考えて、インスタンスメソッドにすべきです。
例題で静的メソッドの感覚を固める
例1:ID 採番するクラス
class IdGenerator {
static current = 0;
static next() {
this.current++;
return this.current;
}
}
console.log(IdGenerator.next()); // 1
console.log(IdGenerator.next()); // 2
console.log(IdGenerator.next()); // 3
JavaScriptインスタンスを作る必要がない「機能だけのクラス」です。
クラス全体で共有したい状態(current)と、それを操作する静的メソッド(next)を持っています。
例2:文字列ユーティリティをクラスでまとめる
class StringUtil {
static toCamel(str) {
return str.replace(/-([a-z])/g, (_, ch) => ch.toUpperCase());
}
static toKebab(str) {
return str.replace(/[A-Z]/g, ch => "-" + ch.toLowerCase());
}
}
console.log(StringUtil.toCamel("user-name")); // userName
console.log(StringUtil.toKebab("userName")); // user-name
JavaScriptインスタンスはいらないが、「文字列操作系」をひとまとめにしたい場合に静的メソッドが便利です。
例3:JSON からの復元を静的メソッドにまとめる
class User {
constructor(id, name) {
this.id = id;
this.name = name;
}
describe() {
console.log(`${this.id}: ${this.name}`);
}
static fromJson(jsonStr) {
const obj = JSON.parse(jsonStr);
return new User(obj.id, obj.name);
}
}
const json = '{"id":1,"name":"Alice"}';
const user = User.fromJson(json);
user.describe(); // 1: Alice
JavaScript静的メソッド fromJson を通すことで、
「JSON から User をどう復元するか」というロジックをクラス側に閉じ込められます。
まとめ
静的メソッドの核心は、
「インスタンスではなく、“クラスそのもの”に属するメソッド。クラス名から直接呼ぶ」 という点です。
押さえておきたいポイントは次のとおりです。
static メソッド名() { ... }で定義し、クラス名.メソッド名()で呼ぶ- インスタンスメソッドとは違い、インスタンスではなくクラスに紐づく
- インスタンスに依存しない処理(ユーティリティ、工場メソッド、クラス共通状態の扱い)に向いている
- 静的メソッドは継承され、子クラスでオーバーライドしたり
superで親を呼んだりできる - インスタンスからは呼べないし、静的メソッド内の
thisは「インスタンス」ではない
まずは、自分で作ったクラスに
「1つ静的メソッドを足してみる」ところから始めてみてください。
“インスタンスに属さないけど、このクラスの仲間として置いておきたい処理”が見えてきたとき、
静的メソッドの気持ちよさを実感できるはずです。
