aboutsummaryrefslogtreecommitdiff
path: root/files/de/web/javascript/reference/global_objects/function/name/index.html
blob: 29a3903d56b983585c1928966a9df35b94356950 (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
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
---
title: Function.name
slug: Web/JavaScript/Reference/Global_Objects/Function/name
tags:
  - ECMAScript 2015
  - Function
  - JavaScript
  - Property
translation_of: Web/JavaScript/Reference/Global_Objects/Function/name
---
<div>{{JSRef}}</div>

<p><span class="seoSummary">Die nur lesende Eigenschaft <code><strong>name</strong></code> eines {{jsxref("Function")}} Objektes welche den Namen, der beim erstellen angegeben wurde enthält oder <code>"anonymous"</code> für anonyme Funktionen.</span></p>

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



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

<div> </div>

<div class="note">
<p>Zu beachten ist, dass in nicht standardisierten implementierungen vor ES2015 das <code>configurable</code> Attribute ebenfalls <code>false</code> ist.</p>
</div>

<h2 id="Beispiele">Beispiele</h2>

<h3 id="Name_bei_Funktionsanweisungen">Name bei Funktionsanweisungen</h3>

<p>Die <code>name</code> Eigenschaft gibt den Namen einer Funktionsanweisung:</p>

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

<h3 id="Name_bei_Function_Konstruktoren">Name bei <code>Function</code> Konstruktoren</h3>

<p>Funktionen, die mit der Syntax <code>new Function(...)</code> oder nur <code>Function(...)</code> erstellt werden, erstellen {{jsxref("Function")}}  mit dem Namen "anonymous".</p>

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

<h3 id="Gefolgerte_Funktionsnamen">Gefolgerte Funktionsnamen</h3>

<p>Bei Variablen und Methoden kann der Name von anonymen Funktionen von ihrer syntaktischen Position gefolgert werden (neu in 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>Funktionen mit einem Namen lassen sich mittels {{jsxref("Operators/Function", "Funktionanweisung", "", 1)}} definieren:</p>

<pre class="brush: js">var object = {
  someMethod: function object_someMethod() {}
};
console.log(object.someMethod.name); // logs "object_someMethod"

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

<p>Man kann den Namen einer Funktion nicht ändern, weil diese Eigenschaft schreibgeschützt ist:</p>

<div class="hidden">
<p>Example below contradicts with what is said at the beginning of this section and doesn't work as described.</p>
</div>

<pre class="brush: js">var object = {
  // anonyme Funktionsdefinition
  someMethod: function() {}
};

object.someMethod.name = 'someMethod';
console.log(object.someMethod.name); // leerer String, someMethod ist anonym
</pre>

<p>Um sie zu ändern, kann {{jsxref("Object.defineProperty()")}} eingesetzt werden.</p>

<h3 id="Kurzform_von_Methodennamen">Kurzform von Methodennamen</h3>

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

<h3 id="Gebundene_Funktionsnamen">Gebundene Funktionsnamen</h3>

<p>{{jsxref("Function.bind()")}} erzeugt eine Funktion mit dem Namen, der sich aus <code> "bound "</code> und dem Namen der Funktion zusammensetzt.</p>

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

<h3 class="brush: js" id="Funktionsnamen_für_Getter_und_Setter">Funktionsnamen für Getter und Setter</h3>

<p>Beim Einsatz von <code><a href="/de/docs/Web/JavaScript/Reference/Functions/get">get</a></code> und <code><a href="/de/docs/Web/JavaScript/Reference/Functions/set">set</a></code> Zugriffseigenschaften wird "get" oder "set" im Funktionsnamen auftauchen.</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="Funktionsnamen_in_Klassen">Funktionsnamen in Klassen</h3>

<p>Über <code>obj.constructor.name</code> lässt sich die "Klasse" eines Objekts überprüfen (jedoch sollten die unten stehende Warnung berücksichtigt werden):</p>

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

var fooInstance = new Foo();
console.log(fooInstance.constructor.name); // logs "Foo"
</pre>

<div class="warning">
<p><strong>Warnung:</strong> Der Skriptinterpreter wird die eingebaute <code>Function.name</code> Eigenschaft nur setzen, wenn eine Funktion keine eigene Eigenschaft mit dem Namen <em>name</em> hat (siehe Kapitel <a href="https://www.ecma-international.org/ecma-262/6.0/#sec-setfunctionname">9.2.11 der ECMAScript2015 Sprachdefinition</a>). Jedoch spezifiziert ES2015 das <em>static</em> Schlüsselwort so, dass statische Methoden als eigene Eigenschaft des Klassenkonstruktorfunktion gesetzt wird (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>Aus diesem Grund kann der Klassenname für jede Klasse mit einer statischen Methodeneigenschaft <code>name()</code> nicht bestimmt werden:</p>

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

<p>Mit einer <code>static name()</code> Methode hält <code>Foo.name</code> nicht mehr den aktuellen Klassennamen bereit, sondern eine Referenz zu dem <code>name()</code> Funktionsobjekt. Die oben stehende Klassendefinition in ES2015 Syntax kann in ES5 Syntax für Chrome oder Firefox wie folgt übersetzt werden:</p>

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

<p>Beim Versuch die Klasse von <code>fooInstance</code> mithilfe von <code>fooInstance.constructor.name</code> herauszufinden, bekommt man nicht den Klassennamen, sondern eine Referenz auf die statische Methode. Beispiel:</p>

<pre class="brush: js">var fooInstance = new Foo();
console.log(fooInstance.constructor.name); // logs function name()
</pre>

<p>Man sieht zudem in der Beispiel  der ES5 Syntax für Chrome und Firefox, dass die Definition der statischen <code>Foo.name</code> Methode überschreibbar (<em>writable</em>) wird. Wird nicht angegeben, ist der Standard für solche Definition nur lesend (<em>read-only</em>).</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>Aus diesem Grund darf man sich nicht darauf verlassen, dass <code>Function.name</code> immer den Klassennamen zurück gibt.</p>

<h3 id="Symbols_als_Funktionsnamen">Symbols als Funktionsnamen</h3>

<p>Wenn ein {{jsxref("Symbol")}} als Funktionsnamen genutzt wird und das Symbol eine Beschreibung (description) hat, ist der Methodennamen gleich der Beschreibung in eckigen Klammern.</p>

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

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

<h2 id="JavaScript-Kompressoren_und_-Minimierer">JavaScript-Kompressoren und -Minimierer</h2>

<div class="warning">
<p><strong>Warnung:</strong> Beim der Benutzung von <code>Function.name</code> ist Vorsicht geboten, wenn Codetransformtionen, wie JavaScript Kompressoren (Minimierer) oder Obfuscators, zum Einsatz kommen. Diese Werkzeuge werden häufig im Zuge von Werkzeugketten zum Bauen von JavaScript-Programmen eingesetzt um die Größe eines Programms zu für den Produktivbetrieb zu minimieren. Solche Werkzeuge ändern die Funktionsnamen häufig beim Erstellen.</p>
</div>

<p>Quelltext wie dieser:</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>wird manchmal zu folgendem Quelltext komprimiert:</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>In der nicht komprimierten Version läuft das Programm in den true-Zweig und gibt <code><em>'foo' is an instance of 'Foo'</em></code> aus. Die komprimierte Version verhält sich anders und läuft in den else-Zweig. Wenn man sich <code>Function.name</code> zurückerinnert, wie in obigen Beispielen, muss beachtet werden, dass Kompressoren die Methodennamen nicht ändert oder nicht annimmt, dass eine Funktion nur in diesem Quelltext benutzt.</p>

<h2 id="Spezifikationen">Spezifikationen</h2>

<table class="standard-table">
 <tbody>
  <tr>
   <th scope="col">Spezifikation</th>
   <th scope="col">Status</th>
   <th scope="col">Kommentar</th>
  </tr>
  <tr>
   <td>{{SpecName('ES2015', '#sec-name', 'name')}}</td>
   <td>{{Spec2('ES2015')}}</td>
   <td>Initiale Definition.</td>
  </tr>
  <tr>
   <td>{{SpecName('ESDraft', '#sec-function-instances-name', 'name')}}</td>
   <td>{{Spec2('ESDraft')}}</td>
   <td> </td>
  </tr>
 </tbody>
</table>

<h2 id="Browserkompatibilität">Browserkompatibilität</h2>

<div>

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