new.target

new.target プロパティを使用すると、関数やコンストラクタが new 演算子を使用して呼び出されたかどうかを検出できます。コンストラクタや関数内で、new 演算子でインスタンス生成すると、new.target はコンストラクタや関数への参照を返します。通常の関数呼び出しの場合、new.targetundefined です。

構文

new.target

概要

new.target の構文は、new キーワードとドット、プロパティ名 target で構成されています。通常、ドットの左側はプロパティアクセスが行われるオブジェクトですが、ここでの new はオブジェクトではありません。

new.target プロパティは、すべての関数で使用できる疑似的なプロパティです。

クラスのコンストラクタでは、構築されたクラスを参照します。

通常の関数では、new 演算子を介して呼び出されたと仮定して、関数自体を参照します。それ以外の場合、new.targetundefined です。

アロー関数では、new.target は周囲のスコープから継承されます。

関数呼び出しにおいての new.target の使用

通常の関数呼び出しでは(コンストラクタ関数の呼び出しとは反対に)、new.targetundefined です。これにより、関数がコンストラクタとして new で呼び出されたかを検出できます。

function Foo() {
  if (!new.target) { throw 'Foo() must be called with new' }
  console.log('Foo instantiated with new')
}

new Foo()  // logs "Foo instantiated with new"
Foo()      // throws "Foo() must be called with new"

コンストラクタにおいての new.target

クラスコンストラクタで、new.targetnew で直接実行されたコンストラクタを参照します。これは、コンストラクタは親クラスにあり、子コンストラクタからデリゲートされた場合も同様です。

class A {
  constructor() {
    console.log(new.target.name)
  }
}

class B extends A { constructor() { super() } }

let a = new A()  // logs "A"
let b = new B()  // logs "B"

class C { constructor() { console.log(new.target)  } }
class D extends C { constructor() { super()  } }

let c = new C()  // logs class C{constructor(){console.log(new.target);}}
let d = new D()  // logs class D extends C{constructor(){super();}}

上記のクラス CD の例から、new.target は初期化されたクラスのクラス定義を指しているように見えます。たとえば、dnew D() で初期化した場合は、D のクラス定義が出力され、同様に c の場合は C のクラスが出力されます。

仕様

仕様書
ECMAScript (ECMA-262)
Built-in Function Objects の定義

仕様

仕様書
ECMAScript (ECMA-262)
Built-in Function Objects の定義

ブラウザー実装状況

BCD tables only load in the browser

関連情報