Movatterモバイル変換


[0]ホーム

URL:


MDN Web Docs

このページはコミュニティーの尽力で英語から翻訳されました。MDN Web Docs コミュニティーについてもっと知り、仲間になるにはこちらから。

constructor

BaselineWidely available

constructor メソッドは、クラスで作成されたオブジェクトインスタンスの生成と初期化を行うための特殊なメソッドです。

メモ:このページではconstructor の構文を紹介します。すべてのオブジェクトに存在するconstructor プロパティについては、Object.prototype.constructor を参照してください。

試してみましょう

class Polygon {  constructor() {    this.name = "Polygon";  }}const poly1 = new Polygon();console.log(poly1.name);// Expected output: "Polygon"

構文

js
constructor() { /* … */ }constructor(argument0) { /* … */ }constructor(argument0, argument1) { /* … */ }constructor(argument0, argument1, /* …, */ argumentN) { /* … */ }

追加の構文上の制約があります。

解説

コンストラクターを使用すると、インスタンス化されたオブジェクトに対して、他のメソッドを呼び出す前に行う必要のある独自の初期化を行うことができます。

js
class Person {  constructor(name) {    this.name = name;  }  introduce() {    console.log(`こんにちは、私は${this.name}です。`);  }}const otto = new Person("オットー");otto.introduce(); // こんにちは、私はオットーです。

独自のコンストラクターを提供しなかった場合は、既定のコンストラクターが提供されます。クラスが基底クラスである場合、既定のコンストラクターは空です。

js
constructor() {}

クラスが派生クラスの場合、既定のコンストラクターが親コンストラクターを呼び出し、与えられた引数を渡します。

js
constructor(...args) {  super(...args);}

メモ:上記のような明示的なコンストラクターと既定のコンストラクターの異なる点は、後者が実際には配列イテレーターを呼び出して引数のスプレッドを行わないことです。

それがこのようなコードを動作させることができます。

js
class ValidationError extends Error {  printCustomerMessage() {    return `Validation failed :-( (details: ${this.message})`;  }}try {  throw new ValidationError("Not a valid phone number");} catch (error) {  if (error instanceof ValidationError) {    console.log(error.name); // これは ValidationError の代わりのエラー    console.log(error.printCustomerMessage());  } else {    console.log("Unknown error", error);    throw error;  }}

ValidationError クラスは、独自の初期化を行う必要がないため、明示的なコンストラクターは必要ありません。既定のコンストラクターは、与えられた引数から親のError の初期化を行います。

ただし、独自のコンストラクターを提供し、クラスが親クラスから派生している場合は、super() を使用して親クラスのコンストラクターを明示的に呼び出す必要があります。例えば、以下のようになります。

js
class ValidationError extends Error {  constructor(message) {    super(message); // 親クラスのコンストラクターの呼び出し    this.name = "ValidationError";    this.code = "42";  }  printCustomerMessage() {    return `検証に失敗しました :-( (details: ${this.message}, code: ${this.code})`;  }}try {  throw new ValidationError("正しい電話番号ではありません。");} catch (error) {  if (error instanceof ValidationError) {    console.log(error.name); // これは ValidationError になる    console.log(error.printCustomerMessage());  } else {    console.log("未知のエラーです", error);    throw error;  }}

クラスでnew を使用すると、以下の段階を踏みます。

  1. (派生クラスの場合)super() 呼び出しが評価される前のconstructor 本体。この部分はまだ初期化されていないので、this にアクセスしてはいけません。
  2. (派生クラスの場合)super() 呼び出しが評価され、同じ処理で親クラスが初期化されます。
  3. 現在のクラスのフィールドが初期化されます。
  4. super() 呼び出し後のconstructor 本体(基底クラスの場合は本体全体)が評価されます。

constructor 本体の中では、this で作成されるオブジェクトにアクセスしたりnew で呼び出されるクラスにnew.target でアクセスしたりすることができます。メソッド(ゲッターセッターを含む)とプロトタイプチェーンconstructor が実行される前にthis で初期化されているので、スーパークラスのコンストラクターからサブクラスのメソッドにアクセスすることもできることに注意してください。しかし、これらのメソッドがthis を使用している場合、this はまだ完全に初期化されていません。これは、派生クラスのパブリックフィールドを読むとundefined になり、プライベートフィールドを読むとTypeError になるということです。

js
new (class C extends class B {  constructor() {    console.log(this.foo());  }} {  #a = 1;  foo() {    return this.#a; // TypeError: Cannot read private member #a from an object whose class did not declare it    // これは、クラスが宣言していないのではなく、スーパークラスの    // コンストラクターが実行されている時点で、プライベートフィールドが    // まだ初期化されていないため。  }})();

constructor メソッドは返値を持つことができます。基底クラスはコンストラクターから何らかの値を返すことができますが、派生クラスはオブジェクトまたはundefined を返すか、TypeError を発生させなければなりません。

js
class ParentClass {  constructor() {    return 1;  }}console.log(new ParentClass()); // ParentClass {}// 返値はオブジェクトではないので無視される。 これはコンストラクター関数と同じ。class ChildClass extends ParentClass {  constructor() {    return 1;  }}console.log(new ChildClass()); // TypeError: Derived constructors may only return object or undefined

親クラスのコンストラクターがオブジェクトを返した場合、そのオブジェクトは派生クラスのクラスフィールドを定義する際の値として使用します。このトリックは「返値の上書き」と呼ばれ、派生クラスのフィールド(プライベートなものも含む)を無関係なオブジェクトに定義することができます。

constructor は通常のメソッド構文に従うので、デフォルト引数残余引数などをすべて使用することができます。

js
class Person {  constructor(name = "名無し") {    this.name = name;  }  introduce() {    console.log(`こんにちは、私は${this.name}`);  }}const person = new Person();person.introduce(); // こんにちは、私は名無し

コンストラクターはリテラル名でなければなりません。計算プロパティ名はコンストラクターにはなれません。

js
class Foo {  // これは計算プロパティ名です。コンストラクターとしてピックアップされることはありません。  ["constructor"]() {    console.log("called");    this.a = 1;  }}const foo = new Foo(); // ログ出力なしconsole.log(foo); // Foo {}foo.constructor(); // "called" と出力console.log(foo); // Foo { a: 1 }

非同期メソッド、ジェネレーターメソッド、アクセサ、クラスフィールドはconstructor と名付けることは禁止されています。プライベートな名前を#constructor と呼び出すことはできません。constructor という名前のメンバーはプレーンなメソッドでなければなりません。

constructor メソッドの使用

このコードスニペットは、classes sample (ライブデモ) から転載しています。

js
class Square extends Polygon {  constructor(length) {    // ここでは、ポリゴンの幅と高さを指定された長さにして、親クラスの    // コンストラクターを呼び出しています。    super(length, length);    // メモ: 派生クラスでは、`this` を使用する前に `super()` を呼び出す    // 必要があります。これを省略すると ReferenceError が発生します。    this.name = "Square";  }  get area() {    return this.height * this.width;  }  set area(value) {    this.height = value ** 0.5;    this.width = value ** 0.5;  }}

異なるプロトタイプにバインドされたコンストラクターでの super を呼び出し

super() は現在のクラスのプロトタイプであるコンストラクターを呼び出します。現在のクラスのプロトタイプを変更した場合、super() は新しいプロトタイプのコンストラクターを呼び出します。現在のクラスのprototype プロパティを変更しても、super() が呼び出すコンストラクターには影響しません。

js
class Polygon {  constructor() {    this.name = "Polygon";  }}class Rectangle {  constructor() {    this.name = "Rectangle";  }}class Square extends Polygon {  constructor() {    super();  }}// Polygon の代わりに(基本クラスである) Rectangle を継承するようにするObject.setPrototypeOf(Square, Rectangle);const newInstance = new Square();// newInstance はまだ Polygon のインスタンスです。// Square.prototype のプロトタイプを変更していないので、// newInstance のプロトタイプチェーンは以下のままです。//   newInstance --> Square.prototype --> Polygon.prototypeconsole.log(newInstance instanceof Polygon); // trueconsole.log(newInstance instanceof Rectangle); // false// ただし、 super() はコンストラクターとして Rectangle を呼び出すため、// newInstance の name プロパティは Rectangle のロジックで初期化されます。console.log(newInstance.name); // Rectangle

仕様書

Specification
ECMAScript® 2026 Language Specification
# sec-static-semantics-constructormethod

ブラウザーの互換性

関連情報

Help improve MDN

Learn how to contribute.

This page was last modified on byMDN contributors.


[8]ページ先頭

©2009-2025 Movatter.jp