Function オブジェクトの読み取り専用プロパティ name は、作成時に付けられた名前、もしくは無名関数の場合は "anonymous" を返します。

Function.name のプロパティ属性
書込可能 不可
列挙可能 不可
設定可能

 
非標準であった ES2015 以前の実装では、configurable 属性も false であることに注意してください。

関数文の名前

name プロパティは関数文の名前を返します。

function doSomething() {}
doSomething.name; // "doSomething"

関数コンストラクタの名前

構文 new Function(...) または単に Function(...) で関数を作成すると、Function オブジェクトが作成され、その名前は "anonymous" になります。

(new Function).name; // "anonymous"

Inferred function names

変数とメソッドは、構文上の位置から無名関数の名前を推論できます (ECMAScript 2015 から)。

let f = function() {};
let object = {
  someMethod: function() {}
};

console.log(f.name); // "f"
console.log(object.someMethod.name); // "someMethod"

関数式 で、name を持つ関数を定義することができます:

let object = {
  someMethod: function object_someMethod() {}
};
console.log(object.someMethod.name); // "object_someMethod" と表示

try { object_someMethod } catch(e) { console.log(e); }
// ReferenceError: object_someMethod is not defined

このプロパティは読み取り専用であり、関数の name を変更することはできません:

 let object = {
  // someMethod
  someMethod: function() {}
};

object.someMethod.name = 'otherMethod';
console.log(object.someMethod.name); // someMethod

name を変更したければ、Object.defineProperty() を使ってください。

短縮メソッドの名前

var o = {
  foo(){}
};
o.foo.name; // "foo";

バインドされた関数の名前

Function.bind() が関数を作成する時、その名前は "bound " とその関数名を合わせたものとなります。

function foo() {}; 
foo.bind({}).name; // "bound foo"

ゲッターとセッターの関数名

gettersetter を使う時は、"get" や "set" が関数名に含まれます。

let o = { 
  get foo(){}, 
  set foo(x){} 
}; 

var descriptor = Object.getOwnPropertyDescriptor(o, "foo"); 
descriptor.get.name; // "get foo" 
descriptor.set.name; // "set foo";

クラスでの関数名

obj.constructor.name でオブジェクトの「クラス」を知ることができます (ただし、下記の警告を確認してください):

function Foo() {}  // ES2015 構文の場合: class Foo {}

var fooInstance = new Foo();
console.log(fooInstance.constructor.name); // "Foo" と表示

警告: スクリプトインタープリターは、関数が自身の name プロパティを持っていない場合に限り、組み込みの Function.name プロパティを設定します (9.11.2. of the ECMAScript2015 Language Specification セクションをご覧ください)。しかしES2015では、static キーワードを指定すると、その静的メソッドはクラスのコンストラクタ関数の OwnProperty として設定されます (ECMAScript2015, 14.5.14.21.b + 12.2.6.9)。

従って、name() という静的メソッドを持つクラスでは、事実上そのクラス名を取得することはできません:

class Foo {
  constructor() {}
  static name() {}
}

static name() メソッドが存在する場合、Foo.name はクラス名ではなく、 name() 関数オブジェクトへの参照を持つことになります。Chrome や Firefox では、上記の ES2015 の構文によるクラス定義は、下記の ES5 構文のコードと同じような挙動をします:

function Foo() {}
Object.defineProperty(Foo, 'name', { writable: true });
Foo.name = function() {};

fooInstance.constructor.namefooInstance のクラスを取得しようとしても、得られるのはクラス名ではなく静的メソッドへの参照です。例えば:

let fooInstance = new Foo();
console.log(fooInstance.constructor.name); // 関数 name() を表示

先ほどの ES5 の構文の例では、Chrome や Firefox での Foo.name の静的な定義の際に writable を指定しています。このような独自の手法を用いなければ、デフォルトでは read-only となります:

Foo.name = 'Hello';
console.log(Foo.name); // Foo が static name() を持つ場合は "Hello"、そうでなければ "Foo" と表示する。

従って、Function.name プロパティが常にクラス名を保持しているとは考えないほうがいいでしょう。

関数名としての Symbol

Symbol を関数名として使用し、Symbol が description を持っている場合、関数名はブラケット [ ] 内の description となります。

let sym1 = Symbol("foo"); 
let sym2 = Symbol(); 
let o = { 
  [sym1]: function(){}, 
  [sym2]: function(){} 
}; 

o[sym1].name; // "[foo]"
o[sym2].name; // ""

JavaScript の圧縮とミニファイ

警告: Function.name を使用しているときに、JavaScript の圧縮(ミニファイ)や難読化のような変換を行う際には注意が必要です。これらのツールはJavaScript ビルドパイプラインの一部として、本番環境に設置する前にプログラムのサイズを縮小するためによく使用されます。それらの変換は、ビルド時に関数名を変更することがあります。

次のようなソースコードは:

function Foo() {};
let foo = new Foo();

if (foo.constructor.name === 'Foo') {
  console.log("'foo' は 'Foo' のインスタンスである");
} else {
  console.log('おおっと!');
}

このように圧縮されるかもしれません:

function a() {};
let b = new a();
if (b.constructor.name === 'Foo') {
  console.log("'foo' は 'Foo' のインスタンスである");
} else {
  console.log('おおっと!');
}

非圧縮版では、プログラムは真の方の分岐を実行し、「'foo' は 'Foo' のインスタンスである」と表示するのに対し、圧縮版は異なる振る舞いをし、偽の方の分岐を実行します。それゆえ、上述の例のように Function.name に依存するならば、ビルドパイプラインが関数名を変更しないようにするか、特定の関数名を想定しない構造にする必要があります。

仕様

仕様書 策定状況 コメント
ECMAScript 2015 (6th Edition, ECMA-262)
name の定義
標準 初期定義
ECMAScript Latest Draft (ECMA-262)
name の定義
ドラフト  

ブラウザー実装状況

Update compatibility data on GitHub
デスクトップモバイルサーバー
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewAndroid 版 ChromeEdge MobileAndroid 版 FirefoxAndroid 版 OperaiOS 版 SafariSamsung InternetNode.js
基本対応Chrome 完全対応 15Edge 完全対応 14Firefox 完全対応 1IE 未対応 なしOpera 完全対応 ありSafari 完全対応 ありWebView Android 完全対応 ありChrome Android 完全対応 ありEdge Mobile 完全対応 ありFirefox Android 完全対応 4Opera Android 完全対応 ありSafari iOS 完全対応 ありSamsung Internet Android 完全対応 ありnodejs 完全対応 あり
Configurable: trueChrome 完全対応 43Edge ? Firefox 完全対応 38IE ? Opera ? Safari ? WebView Android ? Chrome Android 完全対応 43Edge Mobile ? Firefox Android 完全対応 38Opera Android ? Safari iOS ? Samsung Internet Android 完全対応 4.0nodejs ?
Inferred names on anonymous functionsChrome 完全対応 51Edge ? Firefox 完全対応 53IE ? Opera ? Safari ? WebView Android ? Chrome Android 完全対応 51Edge Mobile ? Firefox Android 完全対応 53Opera Android ? Safari iOS ? Samsung Internet Android 完全対応 5.0nodejs ?

凡例

完全対応  
完全対応
未対応  
未対応
実装状況不明  
実装状況不明

ドキュメントのタグと貢献者

このページの貢献者: sutara79, shimataro, YuichiNukiyama, ethertank, yyss
最終更新者: sutara79,