aboutsummaryrefslogtreecommitdiff
path: root/files/fr/web/javascript/reference/global_objects/function/name/index.html
blob: c580c50ae71d9ee977ced71ecf2926cfbbd58e34 (plain)
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
---
title: Function.name
slug: Web/JavaScript/Reference/Global_Objects/Function/name
tags:
  - ECMAScript 2015
  - Function
  - JavaScript
  - Propriété
  - Reference
translation_of: Web/JavaScript/Reference/Global_Objects/Function/name
original_slug: Web/JavaScript/Reference/Objets_globaux/Function/name
---
<div>{{JSRef}}</div>

<p>La propriété <code><strong><em>function</em>.name</strong></code> est une propriété en lecture seule qui renvoie le nom de la fonction courante ou <code>"anonymous"</code> si celle-ci a été créée de façon anonyme.</p>

<div>{{EmbedInteractiveExample("pages/js/function-name.html")}}</div>



<div>{{js_property_attributes(0,0,1)}}</div>

<div class="note">
<p><strong>Note :</strong> Dans les implémentations non-standards antérieures à ES2015, l'attribut <code>configurable</code> valait <code>false</code>.</p>
</div>

<h2 id="Exemples">Exemples</h2>

<h3 id="Instruction_de_fonction">Instruction de fonction</h3>

<p>La propriété <code>name</code> renvoie le nom de la fonction lorsque celle-ci est utilisée dans une instruction de fonction.</p>

<pre class="brush: js">function faireUnTruc() {}
faireUnTruc.name; // "faireUnTruc"
</pre>

<h3 id="Fonctions_créées_avec_un_constructeur">Fonctions créées avec un constructeur</h3>

<p>Lorsqu'on crée une fonction avec <code>new Function(...)</code> ou simplement <code>Function(...)</code>, on crée uniquement des objets dont le nom est "anonymous".</p>

<pre class="brush: js">(new Function).name; // "anonymous"</pre>

<h3 id="Inférence_des_noms_de_fonction">Inférence des noms de fonction</h3>

<p>Les variables et les méthodes permettent d'inférer (c'est-à-dire de « deviner ») le nom des fonctions anonymes en fonction de leur position syntaxique (cette fonctionnalité est apparue avec ECMAScript 2015).</p>

<pre class="brush: js">var f = function() {};
var objet = {
  uneMéthode: function() {}
};

console.log(f.name); // "f"
console.log(objet.uneMéthode.name); // "uneMéthode"
</pre>

<p>On peut définir une fonction avec un nom grâce à une {{jsxref("Opérateurs/L_opérateur_function", "expression de fonction", "", 1)}}:</p>

<pre class="brush: js">var objet = {
  uneMéthode: function objet_maMéthode() {}
};
console.log(objet.uneMéthode.name); // logs "objet_maMéthode"

try { objet_maMéthode } catch(e) { console.log(e); }
// ReferenceError: objet_maMéthode is not defined
</pre>

<p>On ne peut pas changer le nom d'une fonction, cette propriété est uniquement en lecture :</p>

<pre class="brush: js">var objet = {
  // anonyme
  uneMéthode: function() {}
};

objet.uneMéthode.name = 'uneMéthode';
console.log(object.uneMéthode.name); // une chaîne vide, uneMéthode est anonyme
</pre>

<p>Pour modifier le nom, on pourrait cependant utiliser la méthode {{jsxref("Object.defineProperty()")}}.</p>

<h3 id="Notation_raccourcie_pour_les_méthodes">Notation raccourcie pour les méthodes</h3>

<pre class="brush: js">var o = {
  toto(){}
};
o.toto.name; // "toto";</pre>

<h3 id="Noms_des_fonctions_liées">Noms des fonctions liées</h3>

<p>{{jsxref("Function.bind()")}} produit une fonction dont le nom sera la chaîne "bound " suivi du nom de la fonction.</p>

<pre class="brush: js">function toto() {};
toto.bind({}).name; // "bound toto"
</pre>

<h3 id="Noms_de_fonction_pour_les_accesseurs_et_les_mutateurs">Noms de fonction pour les accesseurs et les mutateurs</h3>

<p>Lorsqu'on utilise les propriétés d'accesseur <code><a href="/fr/docs/Web/JavaScript/Reference/Fonctions/get">get</a></code> / <code><a href="/fr/docs/Web/JavaScript/Reference/Fonctions/set">set</a></code>, "get" ou "set" apparaîtra avant le nom de la fonction.</p>

<pre class="brush: js">var o = {
  get toto(){},
  set toto(x){}
};

var descripteur = Object.getOwnPropertyDescriptor(o, "toto");
descripteur.get.name; // "get toto"
descripteur.set.name; // "set toto";</pre>

<h3 id="Noms_des_fonctions_utilisées_dans_les_classes">Noms des fonctions utilisées dans les classes</h3>

<p>On peut utiliser la notation <code>obj.constructor.name</code> pour vérifier la « classe » d'un objet (attention aux avertissements ci-après) :</p>

<pre class="brush: js">function Toto() {}  // Syntaxe ES2015 : class Toto {}

var instanceDeToto = new Toto();
console.log(instanceDeToto.constructor.name); // affiche "Toto" dans la console
</pre>

<p><strong>Attention :</strong> l'interpréteur utilisera la propriété native <code>Function.name</code> uniquement si la fonction ne possède pas une propriété en propre intitulée <em>name</em> (cf section <a href="https://www.ecma-international.org/ecma-262/6.0/#sec-setfunctionname">9.2.11 de la spécification ECMAScript2015</a>). Cependant, ES2015 indique que les propriétés définies avec mot-clé <em>static</em> seront des propriétés propres de la fonction constructrice (cf. 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>). Ainsi, il n'est plus possible d'obtenir le nom de la classe si celle-ci possède une méthode statique intitulée <code>name()</code> :</p>

<pre class="brush: js">class Toto {
  constructor() {}
  static name() {}
}
</pre>

<p>Avec <code>static name()</code>, <code>Toto.name</code> ne contient plus le nom de la classe mais une référence à l'objet <code>name()</code>. La définition utilisée ci-avant se comporte de façon semblable à ce fragment de code ES5 :</p>

<pre class="brush: js">function Toto() {}
Object.defineProperty(Toto, 'name', { writable: true });
Toto.name = function() {};
</pre>

<p>Il est donc parfois erroné de penser que <code>Function.name</code> pointe toujours vers le nom de la classe.</p>

<h3 id="Noms_de_fonction_sous_la_forme_de_symboles">Noms de fonction sous la forme de symboles</h3>

<p>Si un symbole ({{jsxref("Symbol")}}) est utilisé comme nom d'une fonction et que celui-ci dispose d'une description, c'est cette dernière qui sera utilisée comme nom de la méthode, entre crochets :</p>

<pre class="brush: js">var sym1 = Symbol("Toto");
var sym2 = Symbol();
var o = {
  [sym1]: function(){},
  [sym2]: function(){}
};

o[sym1].name; // "[Toto]"
o[sym2].name; // ""</pre>

<h2 id="Compresseurs_et_outils_de_minification_JavaScript">Compresseurs et outils de minification JavaScript</h2>

<p>Attention à l'utilisation de <code>Function.name</code> lorsque le code source est transformé par certains outils. En effet, ceux-ci réduisent généralement la taille d'un programme en compressant les espaces et en modifiant parfois les noms de variables. Ainsi, un fragment de code comme :</p>

<pre class="brush: js">function Toto() {};
var toto = new Toto();

if (Toto.constructor.name === 'Toto') {
  console.log("'toto' est une instance de 'Toto'");
} else {
  console.log('Oups !');
}
</pre>

<p>pourrait être compressé en :</p>

<pre class="brush: js">function a() {};
var b = new a();
if (b.constructor.name === 'Toto') {
  console.log("'toto' est une instance de 'Toto'");
} else {
  console.log('Oups !');
}
</pre>

<p>Dans la version non-compressée, la condition du test est remplie et on affiche <em>'toto' est une instance de 'Toto'</em> dans la console. Mais dans la version compressée, la condition n'est pas vérifiée. Lorsqu'on utilise <code>name</code>, il faut s'assurer que les outils utilisés ne modifient pas le nom des fonctions.</p>

<h2 id="Spécifications">Spécifications</h2>

<table class="standard-table">
 <tbody>
  <tr>
   <th scope="col">Spécification</th>
   <th scope="col">État</th>
   <th scope="col">Commentaires</th>
  </tr>
  <tr>
   <td>{{SpecName('ES2015', '#sec-name', 'name')}}</td>
   <td>{{Spec2('ES2015')}}</td>
   <td>Définition initiale.</td>
  </tr>
  <tr>
   <td>{{SpecName('ESDraft', '#sec-function-instances-name', 'name')}}</td>
   <td>{{Spec2('ESDraft')}}</td>
   <td></td>
  </tr>
 </tbody>
</table>

<h2 id="Compatibilité_des_navigateurs">Compatibilité des navigateurs</h2>

<p>{{Compat("javascript.builtins.Function.name")}}</p>