A propriedade somente-leitura name de um objeto Function indica o nome da função como especificado quando esta foi criada, ou "anonymous" para funções criadas anonimamente.

Property attributes of Function.name
Writable no
Enumerable no
Configurable yes

 

Note que em implementações não-standard anteriores à ES2015 o atributo configurable tinha também o valor false.

Exemplos

Nome de declaração da função

A propriedade name retorna o nome de uma declaração de função.

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

Nome do construtor da função

Funções criadas com a sintaxe new Function(...) ou somente Function(...) criam objetos Function com o nome "anonymous".

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

Nomes de função inferidos

Variáveis e métodos podem inferir o nome de uma função anônima a partir de sua posição sintática (novo na ECMAScript 2015).

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

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

Você pode definir uma função com um nome numa expressão de função:

var object = {
  someMethod: function object_someMethod() {}
};
console.log(object.someMethod.name); // grava o log "object_someMethod"

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

Você não pode mudar o nome de uma função, pois a propriedade é somente-leitura:

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

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

Para mudá-lo, você poderia no entanto usar Object.defineProperty().

Nomes curtos de métodos

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

Nomes de funções vinculadas

Function.bind() produz uma função cujo nome é "bound " seguido do nome da função.

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

Nomes de função para getters e setters

Ao usar propriedades acessórias get e set, "get" ou "set" aparecerão no nome da função.

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

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

Nomes de funções em classes

Você pode usar obj.constructor.name para checar a "classe" de um objeto (porém leia com atenção os avisos abaixo):

function Foo() {}  // Sintaxe ES2015: class Foo {}

var fooInstance = new Foo();
console.log(fooInstance.constructor.name); // grava o log "Foo"

Aviso: O interpretador vai definir a propriedade  interna Function.name somente se uma função não tiver uma propriedade já com o nome name (veja a seção 9.2.11 da ECMAScript2015 Language Specification). Porém, a ES2015 especifica que a palavra-chave static de maneira que métodos estáticos serão definidos como OwnProperty da função construtora de classe (ECMAScript2015, 14.5.14.21.b + 12.2.6.9).

Portanto não podemos obter o nome de virtualmente qualquer classe com um método estático name():

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

Com um método static name(), Foo.name não guarda mais o nome verdadeiro da classe mas uma referência ao objeto de função name(). A definição de classe acima, escrita em sintaxe ES2015, se comportará de maneira similar ao seguinte trecho de código em sintaxe ES5 no Chrome ou no Firefox:

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

Tentar obter a classe de fooInstance via fooInstance.constructor.name não nos dará de maneira alguma o nome da classe, mas sim uma referência ao método estático da classe. Exemplo:

var fooInstance = new Foo();
console.log(fooInstance.constructor.name); // grava o name() da função no log

Você pode ver também, a partir do exemplo de sintaxe ES5, que, no Chrome ou no Firefox, a nossa definição estática de Foo.name se torna writable. A predefinição interna na ausência de uma definição estática customizada é somente-leitura:

Foo.name = 'Hello';
console.log(Foo.name); // logs "Hello" if class Foo has a static name() property but "Foo" if not.

Portanto, você não pode assumir que a propriedade interna Function.name sempre guardará um nome de classe..

Símbolos como nome de função

Se um Symbol é usado como nome de função e o símbolo tem uma descrição, o nome do método será a descrição entre colchetes.

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

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

Compressores e minificadores JavaScript

Aviso: Tenha cuidado ao usar Function.name e transformações de código-fonte, como aquelas executadas por compressores (minificadores) ou obfuscadores de JavaScript. Estas ferramentas são comumente usadas como parte de processos de build  de JavaScript para reduzir os tamanhos de programas antes da implementação em produção. Tais transformações frequentemente mudam nomes de função durante o build.

Código fonte do tipo:

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

if (foo.constructor.name === 'Foo') {
  console.log("'foo' is an instance of 'Foo'");
} else {
  console.log('Oops!');
}

pode ser comprimido e se tornar:

function a() {};
var b = new a();
if (b.constructor.name === 'Foo') {
  console.log("'foo' is an instance of 'Foo'");
} else {
  console.log('Oops!');
}

Na versão descomprimida, o programa cai no bloco-verdade e grava o log 'foo' is an instance of 'Foo'. Todavia, na versão comprimida ele se comporta diferentemente, e cai no bloco else. Se você depende de Function.name, como no exemplo acima, tenha certeza que seu processo de build não mude nomes de função, ou então não assuma que uma função terá um nome determinado.

Especificações

Specification Status Comment
ECMAScript 2015 (6th Edition, ECMA-262)
The definition of 'name' in that specification.
Padrão Definição inicial.
ECMAScript Latest Draft (ECMA-262)
The definition of 'name' in that specification.
Rascunho  

Compatibilidade de navegadores

Update compatibility data on GitHub
DesktopMobileServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidEdge MobileFirefox for AndroidOpera for AndroidiOS SafariSamsung InternetNode.js
Basic supportChrome 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 YesEdge Mobile 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 ? Opera ? Safari ? WebView Android ? Chrome Android Full support 43Edge Mobile ? Firefox 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 ? Opera ? Safari ? WebView Android ? Chrome Android Full support 51Edge Mobile ? Firefox 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

Etiquetas do documento e colaboradores

Colaboradores desta página: leo-ls
Última atualização por: leo-ls,