--- 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 ---
Die nur lesende Eigenschaft name
eines {{jsxref("Function")}} Objektes welche den Namen, der beim erstellen angegeben wurde enthält oder "anonymous"
für anonyme Funktionen.
Zu beachten ist, dass in nicht standardisierten implementierungen vor ES2015 das configurable
Attribute ebenfalls false
ist.
Die name
Eigenschaft gibt den Namen einer Funktionsanweisung:
function doSomething() {} doSomething.name; // logs "doSomething"
Function
KonstruktorenFunktionen, die mit der Syntax new Function(...)
oder nur Function(...)
erstellt werden, erstellen {{jsxref("Function")}} mit dem Namen "anonymous".
(new Function).name; // "anonymous"
Bei Variablen und Methoden kann der Name von anonymen Funktionen von ihrer syntaktischen Position gefolgert werden (neu in ECMAScript 2015).
var f = function() {}; var object = { someMethod: function() {} }; console.log(f.name); // "f" console.log(object.someMethod.name); // "someMethod"
Funktionen mit einem Namen lassen sich mittels {{jsxref("Operators/Function", "Funktionanweisung", "", 1)}} definieren:
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
Man kann den Namen einer Funktion nicht ändern, weil diese Eigenschaft schreibgeschützt ist:
Example below contradicts with what is said at the beginning of this section and doesn't work as described.
var object = { // anonyme Funktionsdefinition someMethod: function() {} }; object.someMethod.name = 'someMethod'; console.log(object.someMethod.name); // leerer String, someMethod ist anonym
Um sie zu ändern, kann {{jsxref("Object.defineProperty()")}} eingesetzt werden.
var o = { foo(){} }; o.foo.name; // "foo";
{{jsxref("Function.bind()")}} erzeugt eine Funktion mit dem Namen, der sich aus "bound "
und dem Namen der Funktion zusammensetzt.
function foo() {}; foo.bind({}).name; // "bound foo"
Beim Einsatz von get
und set
Zugriffseigenschaften wird "get" oder "set" im Funktionsnamen auftauchen.
var o = { get foo(){}, set foo(x){} }; var descriptor = Object.getOwnPropertyDescriptor(o, "foo"); descriptor.get.name; // "get foo" descriptor.set.name; // "set foo"
Über obj.constructor.name
lässt sich die "Klasse" eines Objekts überprüfen (jedoch sollten die unten stehende Warnung berücksichtigt werden):
function Foo() {} // ES2015 Syntax: class Foo {} var fooInstance = new Foo(); console.log(fooInstance.constructor.name); // logs "Foo"
Warnung: Der Skriptinterpreter wird die eingebaute Function.name
Eigenschaft nur setzen, wenn eine Funktion keine eigene Eigenschaft mit dem Namen name hat (siehe Kapitel 9.2.11 der ECMAScript2015 Sprachdefinition). Jedoch spezifiziert ES2015 das static Schlüsselwort so, dass statische Methoden als eigene Eigenschaft des Klassenkonstruktorfunktion gesetzt wird (ECMAScript2015, 14.5.14.21.b + 12.2.6.9).
Aus diesem Grund kann der Klassenname für jede Klasse mit einer statischen Methodeneigenschaft name()
nicht bestimmt werden:
class Foo { constructor() {} static name() {} }
Mit einer static name()
Methode hält Foo.name
nicht mehr den aktuellen Klassennamen bereit, sondern eine Referenz zu dem name()
Funktionsobjekt. Die oben stehende Klassendefinition in ES2015 Syntax kann in ES5 Syntax für Chrome oder Firefox wie folgt übersetzt werden:
function Foo() {} Object.defineProperty(Foo, 'name', { writable: true}); Foo.name = function() {};
Beim Versuch die Klasse von fooInstance
mithilfe von fooInstance.constructor.name
herauszufinden, bekommt man nicht den Klassennamen, sondern eine Referenz auf die statische Methode. Beispiel:
var fooInstance = new Foo(); console.log(fooInstance.constructor.name); // logs function name()
Man sieht zudem in der Beispiel der ES5 Syntax für Chrome und Firefox, dass die Definition der statischen Foo.name
Methode überschreibbar (writable) wird. Wird nicht angegeben, ist der Standard für solche Definition nur lesend (read-only).
Foo.name = 'Hello' console.log(Foo.name); // logs "Hello" if class Foo has a static name() property but "Foo" if not.
Aus diesem Grund darf man sich nicht darauf verlassen, dass Function.name
immer den Klassennamen zurück gibt.
Wenn ein {{jsxref("Symbol")}} als Funktionsnamen genutzt wird und das Symbol eine Beschreibung (description) hat, ist der Methodennamen gleich der Beschreibung in eckigen Klammern.
var sym1 = Symbol("foo"); var sym2 = Symbol(); bar o = { [sym1]: function(){}, [sym2]: function(){} }; o[sym1].name; // "[foo]" o[sym2].name; // ""
Warnung: Beim der Benutzung von Function.name
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.
Quelltext wie dieser:
function Foo() {}; var foo = new Foo(); if (foo.constructor.name === 'Foo') { console.log("'foo' is an instance of 'Foo'"); } else { console.log('Oops!'); }
wird manchmal zu folgendem Quelltext komprimiert:
function a() {}; var b = new a(); if (b.constructor.name === 'Foo') { console.log("'foo' is an instance of 'Foo'"); } else { console.log('Oops!'); }
In der nicht komprimierten Version läuft das Programm in den true-Zweig und gibt 'foo' is an instance of 'Foo'
aus. Die komprimierte Version verhält sich anders und läuft in den else-Zweig. Wenn man sich Function.name
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.
Spezifikation | Status | Kommentar |
---|---|---|
{{SpecName('ES2015', '#sec-name', 'name')}} | {{Spec2('ES2015')}} | Initiale Definition. |
{{SpecName('ESDraft', '#sec-function-instances-name', 'name')}} | {{Spec2('ESDraft')}} |