Function.name

Властивість тільки для читання об'єкта Function name відображає ім'я функції, яке було вказане при створенні, або "anonymous" для анонімних функцій.

Атрибути поля Function.name
Доступний для запису ні
Доступний для переліку ні
Доступний для налаштування так

Зауважте, що у нестандартних реалізаціях до ES2015 атрибут configurable (доступний для налаштування) також мав значення false.

Приклади

Ім'я функції

Властивість name повертає ім'я функції.

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

Ім'я конструктора функції

Функції, створені за допомогою new Function(...) або просто Function(...) створюють об'єкти Function, а їхнє ім'я "anonymous".

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

Виведені імена функцій

Змінні та методи можуть вивести ім'я анонімної функції з її синтаксичної позиції (нове у ECMAScript 2015).

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

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

Ви можете оголосити функцію з ім'ям у функціональному виразі:

var 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

Ви не можете змінювати ім'я функції, ця властивість доступна лише для читання:

var object = {
  // anonymous
  someMethod: function() {}
};

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

Однак, щоб змінити її, ви можете скористатись Object.defineProperty().

Імена лаконічних методів

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

Імена зв'язаних функцій

Метод Function.bind() створює функцію, чиїм ім'ям буде "bound" плюс ім'я функції.

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

Імена функцій для гетерів та сетерів

При використанні властивостей-аксесорів get та set у імені функції з'являється "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"

Застереження: Інтерпретатор коду встановить значення вбудованої властивості Function.name тільки якщо функція не має своєї властивості з назвою name (дивіться розділ 9.2.11 ECMAScript2015 Language Specification). Однак, ES2015 визначає ключове слово static таким чином, що статичні методі встановлюються як OwnProperty функції-конструктора класу (ECMAScript2015, 14.5.14.21.b12.2.6.9).

І тому ми не можемо отримати ім'я класу фактично для жодного класу, що має статичний метод name():

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

З методом static name()Foo.name тепер містить не ім'я класу, а посилання на функцію name(). Наведене вище оголошення класу у синтаксисі ES2015 буде поводитись у Chrome чи Firefox схоже на наступний фрагмент коду у синтаксисі ES5:

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

Спроба отримати клас fooInstance через fooInstance.constructor.name поверне нам зовсім не ім'я класу, а посилання на статичний метод класу. Приклад:

let fooInstance = new Foo();
console.log(fooInstance.constructor.name); // виводить function name()

Ви могли також побачити у прикладі з синтаксисом ES5, що у Chrome чи Firefox наше статичне оголошення Foo.name стає доступним для запису. Вбудоване оголошення за відсутності користувацького статичного методу є доступним лише для читання:

Foo.name = 'Привіт';
console.log(Foo.name);
// виведе "Привіт", якщо клас має статичну властивість name(), інакше виведе "Foo".

Таким чином, не можна розраховувати, що вбудована властивість Function.name завжди міститиме ім'я класу.

Символи в якості імен функцій

Якщо Symbol використовується в якості імені функції і має опис, ім'ям метода буде опис у квадратних дужках.

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'". В той час, як у стиснутій версії вона поводиться по-іншому і виконує гілку else. Якщо ви покладаєтесь на Function.name, як у наведеному вище прикладі, переконайтесь, що ваш конвеєр збірки не змінює імена функцій, або не припускайте, що функція матиме певне ім'я.

Специфікації

Специфікація Статус Коментар
ECMAScript 2015 (6th Edition, ECMA-262)
The definition of 'name' in that specification.
Standard Початкове визначення.
ECMAScript Latest Draft (ECMA-262)
The definition of 'name' in that specification.
Draft

Сумісність з веб-переглядачами

Update compatibility data on GitHub
DesktopMobileServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidFirefox for AndroidOpera for AndroidSafari on iOSSamsung InternetNode.js
nameChrome Full support 15Edge Full support 14Firefox Full support 1IE No support NoOpera Full support YesSafari Full support YesWebView Android Full support YesChrome Android Full support YesFirefox Android Full support 4Opera Android Full support YesSafari iOS Full support YesSamsung Internet Android Full support Yesnodejs Full support Yes
Configurable: trueChrome Full support 43Edge ? Firefox Full support 38IE No support NoOpera Full support 30Safari ? WebView Android Full support 43Chrome Android Full support 43Firefox Android Full support 38Opera Android ? Safari iOS ? Samsung Internet Android Full support 4.0nodejs ?
Inferred names on anonymous functionsChrome Full support 51Edge ? Firefox Full support 53IE No support NoOpera Full support 38Safari ? WebView Android Full support 51Chrome Android Full support 51Firefox Android Full support 53Opera Android ? Safari iOS ? Samsung Internet Android Full support 5.0nodejs ?

Legend

Full support  
Full support
No support  
No support
Compatibility unknown  
Compatibility unknown