1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
|
---
title: Function.name
slug: Web/JavaScript/Reference/Global_Objects/Function/name
translation_of: Web/JavaScript/Reference/Global_Objects/Function/name
---
<div>{{JSRef}}</div>
<p><span class="seoSummary">A propriedade somente-leitura <code><strong>name</strong></code> de um objeto {{jsxref("Function")}} indica o nome da função como especificado quando esta foi criada, ou <code>"anonymous"</code> para funções criadas anonimamente.</span></p>
<div>{{EmbedInteractiveExample("pages/js/function-name.html")}}</div>
<p class="hidden">O código-fonte deste exemplo interativo está mantido em um repositório do GitHub. Se você gostaria de contribuir com o projeto de exemplos interativos, clone por favor <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> e nos envie um <em>pull request</em>.</p>
<div>{{js_property_attributes(0,0,1)}}<br>
</div>
<div class="note">
<p>Note que em implementações não-standard anteriores à ES2015 o atributo <code>configurable</code> tinha também o valor <code>false</code>.</p>
</div>
<h2 id="Exemplos">Exemplos</h2>
<h3 id="Nome_de_declaração_da_função">Nome de declaração da função</h3>
<p>A propriedade <code>name</code> retorna o nome de uma declaração de função.</p>
<pre class="brush: js">function doSomething() {}
doSomething.name; // "doSomething"
</pre>
<h3 id="Nome_do_construtor_da_função">Nome do construtor da função</h3>
<p>Funções criadas com a sintaxe <code>new Function(...)</code> ou somente <code>Function(...)</code> criam objetos {{jsxref("Function")}} com o nome "anonymous".</p>
<pre>(new Function).name; // "anonymous"</pre>
<h3 id="Nomes_de_função_inferidos">Nomes de função inferidos</h3>
<p>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).</p>
<pre class="brush: js">var f = function() {};
var object = {
someMethod: function() {}
};
console.log(f.name); // "f"
console.log(object.someMethod.name); // "someMethod"
</pre>
<p>Você pode definir uma função com um nome numa {{jsxref("Operators/Function", "expressão de função", "", 1)}}:</p>
<pre class="brush: js">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
</pre>
<p>Você não pode mudar o nome de uma função, pois a propriedade é somente-leitura:</p>
<div class="hidden">
<p>O exemplo abaixo contradiz o que é dito no começo desta seção e não funciona como descrito.</p>
</div>
<pre class="brush: js">var object = {
// anonymous
someMethod: function() {}
};
object.someMethod.name = 'otherMethod';
console.log(object.someMethod.name); // someMethod
</pre>
<p>Para mudá-lo, você poderia no entanto usar {{jsxref("Object.defineProperty()")}}.</p>
<h3 id="Nomes_curtos_de_métodos">Nomes curtos de métodos</h3>
<pre class="brush: js">var o = {
foo(){}
};
o.foo.name; // "foo";</pre>
<h3 id="Nomes_de_funções_vinculadas">Nomes de funções vinculadas</h3>
<p>{{jsxref("Function.bind()")}} produz uma função cujo nome é "bound " seguido do nome da função.</p>
<pre class="brush: js">function foo() {};
foo.bind({}).name; // "bound foo"
</pre>
<h3 id="Nomes_de_função_para_getters_e_setters">Nomes de função para <em>getters</em> e <em>setters</em></h3>
<p>Ao usar propriedades acessórias <code><a href="/en-US/docs/Web/JavaScript/Reference/Functions/get">get</a></code> e <code><a href="/en-US/docs/Web/JavaScript/Reference/Functions/set">set</a></code>, "get" ou "set" aparecerão no nome da função.</p>
<pre class="brush: js">var o = {
get foo(){},
set foo(x){}
};
var descriptor = Object.getOwnPropertyDescriptor(o, "foo");
descriptor.get.name; // "get foo"
descriptor.set.name; // "set foo";</pre>
<h3 id="Nomes_de_funções_em_classes">Nomes de funções em classes</h3>
<p>Você pode usar <code>obj.constructor.name</code> para checar a "classe" de um objeto (porém leia com atenção os avisos abaixo):</p>
<pre class="brush: js">function Foo() {} // Sintaxe ES2015: class Foo {}
var fooInstance = new Foo();
console.log(fooInstance.constructor.name); // grava o log "Foo"
</pre>
<div class="warning">
<p><strong>Aviso:</strong> O interpretador vai definir a propriedade interna <code>Function.name</code> somente se uma função não tiver uma propriedade já com o nome <em>name</em> (veja a seção <a href="https://www.ecma-international.org/ecma-262/6.0/#sec-setfunctionname">9.2.11 da ECMAScript2015 Language Specification</a>). Porém, a ES2015 especifica que a palavra-chave <em>static</em> de maneira que métodos estáticos serão definidos como OwnProperty da função construtora de classe (ECMAScript2015, <a href="https://www.ecma-international.org/ecma-262/6.0/#sec-runtime-semantics-classdefinitionevaluation">14.5.14.21.b</a> + <a href="https://www.ecma-international.org/ecma-262/6.0/#sec-object-initializer-runtime-semantics-propertydefinitionevaluation">12.2.6.9</a>).</p>
</div>
<p>Portanto não podemos obter o nome de virtualmente qualquer classe com um método estático <code>name()</code>:</p>
<pre class="brush: js">class Foo {
constructor() {}
static name() {}
}
</pre>
<p>Com um método <code>static name()</code>, <code>Foo.name</code> não guarda mais o nome verdadeiro da classe mas uma referência ao objeto de função <code>name()</code>. 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:</p>
<pre class="brush: js">function Foo() {}
Object.defineProperty(Foo, 'name', { writable: true });
Foo.name = function() {};
</pre>
<p>Tentar obter a classe de <code>fooInstance</code> via <code>fooInstance.constructor.name</code> não nos dará de maneira alguma o nome da classe, mas sim uma referência ao método estático da classe. Exemplo:</p>
<pre class="brush: js">var fooInstance = new Foo();
console.log(fooInstance.constructor.name); // grava o name() da função no log
</pre>
<p>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 <code>Foo.name</code> se torna <em>writable</em>. A predefinição interna na ausência de uma definição estática customizada é somente-leitura:</p>
<pre class="brush: js">Foo.name = 'Hello';
console.log(Foo.name); // logs "Hello" if class Foo has a static name() property but "Foo" if not.
</pre>
<p>Portanto, você não pode assumir que a propriedade interna <code>Function.name</code> sempre guardará um nome de classe..</p>
<h3 id="Símbolos_como_nome_de_função">Símbolos como nome de função</h3>
<p>Se um {{jsxref("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.</p>
<pre>var sym1 = Symbol("foo");
var sym2 = Symbol();
var o = {
[sym1]: function(){},
[sym2]: function(){}
};
o[sym1].name; // "[foo]"
o[sym2].name; // ""</pre>
<h2 id="Compressores_e_minificadores_JavaScript">Compressores e minificadores JavaScript</h2>
<div class="warning">
<p><strong>Aviso:</strong> Tenha cuidado ao usar <code>Function.name</code> 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 <em>build </em>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 <em>build</em>.</p>
</div>
<p>Código fonte do tipo:</p>
<pre class="brush: js">function Foo() {};
var foo = new Foo();
if (foo.constructor.name === 'Foo') {
console.log("'foo' is an instance of 'Foo'");
} else {
console.log('Oops!');
}
</pre>
<p>pode ser comprimido e se tornar:</p>
<pre class="brush: js">function a() {};
var b = new a();
if (b.constructor.name === 'Foo') {
console.log("'foo' is an instance of 'Foo'");
} else {
console.log('Oops!');
}
</pre>
<p>Na versão descomprimida, o programa cai no bloco-verdade e grava o log <em>'foo' is an instance of 'Foo'</em>. Todavia, na versão comprimida ele se comporta diferentemente, e cai no bloco <code>else</code>. Se você depende de <code>Function.name</code>, como no exemplo acima, tenha certeza que seu processo de <em>build</em> não mude nomes de função, ou então não assuma que uma função terá um nome determinado.</p>
<h2 id="Especificações">Especificações</h2>
<table class="standard-table">
<tbody>
<tr>
<th scope="col">Specification</th>
<th scope="col">Status</th>
<th scope="col">Comment</th>
</tr>
<tr>
<td>{{SpecName('ES2015', '#sec-name', 'name')}}</td>
<td>{{Spec2('ES2015')}}</td>
<td>Definição inicial.</td>
</tr>
<tr>
<td>{{SpecName('ESDraft', '#sec-function-instances-name', 'name')}}</td>
<td>{{Spec2('ESDraft')}}</td>
<td> </td>
</tr>
</tbody>
</table>
<h2 id="Compatibilidade_de_navegadores">Compatibilidade de navegadores</h2>
<div>
<div class="hidden">A tabela de compatibilidade nesta página é gerada a partir de dados estruturados. Se você gostaria de contribuir com os dados, confira por favor <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> e nos envie uma <em>pull request</em>.</div>
<p>{{Compat("javascript.builtins.Function.name")}}</p>
</div>
|