Dynamischer Funktionsname in Javascript?

85

Ich habe das:

this.f = function instance(){};

Ich hätte gerne folgendes:

this.f = function ["instance:" + a](){};
Totty.js
quelle
9
Das kannst du nicht. Aber Sie können habenthis["instance"] = function() { }
Raynos
Um zu klären, was Raynos sagte, können Sie tun this["instance" + a] = function() { }. Das war mir nicht klar.
Andrew

Antworten:

7

aktualisieren

Wie bereits erwähnt, ist dies weder die schnellste noch die am meisten empfohlene Lösung. Die unten stehende Lösung von Marcosc ist der richtige Weg.

Sie können eval verwenden:

var code = "this.f = function " + instance + "() {...}";
eval(code);
Mo Valipour
quelle
1
darum habe ich gebeten, danke! (sowieso werde ich diese Funktion nicht verwenden, da sie zu langsam ist)
Totty.js
3
Ich weiß, dass das OP darum gebeten hat, aber das ist eine schreckliche Idee. Nur weil Sie können, heißt das nicht, dass Sie so etwas tun sollten. Es gibt viel bessere Alternativen, die in Bezug auf die Funktionalität fast genau gleich sind.
Thomas Eding
4
@ sg3s: kannst du eine andere lösung vorschlagen?
Tom
2
@ sg3s: Danke für die Beantwortung meines Kommentars! Lassen Sie mich erklären, was ich meinte und was ich eigentlich fragen möchte: Unterscheidet sich Marcoscs Lösung wirklich erheblich von eval? Macht es wirklich einen Unterschied, ob Sie etwas bewerten oder dem Funktionskonstruktor zuführen? Wenn ja, können Sie den Unterschied und seine Auswirkungen erklären? Vielen Dank!
Tom
5
@Tom Für zukünftige Leser: Diese Lösung unterscheidet sich nicht wirklich von Marcoscs Antwort, sie verwenden beide eval()(der FunctionKonstruktor macht das im Inneren).
Kapa
125

Dies wird es im Grunde auf der einfachsten Ebene tun:

"use strict";
var name = "foo";
var func = new Function(
     "return function " + name + "(){ alert('sweet!')}"
)();

//call it, to test it
func();

Wenn Sie mehr Lust haben möchten, habe ich einen Artikel über " Dynamische Funktionsnamen in JavaScript " geschrieben.

Marcosc
quelle
Gute Arbeit! Ich habe das gerade selbst entdeckt und wollte es gerade auf eine dieser Fragen posten, aber du hast mich geschlagen. Ich habe in letzter Zeit viel mit backbone.js gearbeitet und bin es leid, überall in meinem Chrome-Debugger "Kind" zu sehen. Dies löst dieses Problem. Ich frage mich, ob es irgendwelche Auswirkungen auf die Leistung wie die Verwendung von eval gibt.
WebXL
Es gibt auch Auswirkungen auf die Sicherheit. Ich bekomme "Der Funktionskonstruktor ist eval" von jsHint, daher verpacke ich dies in eine Überprüfung des Debug-Modus, da dies der einzige Grund ist, dies zu verwenden. Ich denke, "use strict" verhindert jegliches Durcheinander mit dem globalen Objekt, aber alle Argumente für den Funktionskonstruktor können geändert werden, und was auch immer "dies" ist.
WebXL
Ja, dies für extreme Situationen, in denen Sie im laufenden Betrieb etwas konstruieren müssen.
Marcosc
1
Ich denke ehrlich, stackoverflow.com/a/40918734/2911851 ist eine bessere Lösung, es ist nicht erforderlich, den Hauptteil der Funktion als Zeichenfolge einzuschließen (es sei denn, ich vermisse etwas, aber ich habe es einfach versucht und großartig gearbeitet).
Gian Franco Zabarino
2
AirBnB rät dringend davon ab , da der Funktionskonstruktor evaldas Javascript auswertet und so Ihren Code für eine Reihe von Sicherheitslücken öffnet.
Philippe Hebert
41

Sie können Object.defineProperty wie in der MDN-JavaScript-Referenz [1] angegeben verwenden:

var myName = "myName";
var f = function () { return true; };
Object.defineProperty(f, 'name', {value: myName, writable: false});
  1. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name#Description
Darren
quelle
2
Es scheint, dass dies die Eigenschaft name wie beabsichtigt festlegt. Wenn ich jedoch die Funktion in meinem Browser (neueste Firefox-Entwicklungsversion) protokolliere function fn(), fnwird sie gedruckt und ist der ursprüngliche Name. Seltsam.
Kiara Grouwstra
gleicher Kommentar zu Google Chrome Evergreen. Die Eigenschaft ist ordnungsgemäß festgelegt, aber der Name in der Konsole ist der ursprüngliche Name der Funktion. Vgl. 2ality.com/2015/09/… Es scheint, dass der Name der Funktion bei der Erstellung zugewiesen wurde und nicht geändert werden kann?
user3743222
Auf dieser 2ality.com-Seite finden Sie den nächsten Abschnitt "Ändern des Funktionsnamens" [1], in dem dieselbe Technik beschrieben wird, die in der MDN-Javascript-Referenz enthalten ist. 1. 2ality.com/2015/09/…
Darren
33

In neueren Motoren können Sie dies tun

function nameFunction(name, body) {
  return {[name](...args) {return body(...args)}}[name]
}



const x = nameFunction("wonderful function", (p) => p*2)
console.log(x(9)) // => 18
console.log(x.name) // => "wonderful function"

kybernetikos
quelle
1
Nachdem ich stundenlang versucht hatte, die Lösung herauszufinden, dachte ich nicht einmal daran, ein Objekt mit einem berechneten Eigenschaftsnamen zu verwenden. Genau das, was ich brauchte. Vielen Dank!
Levi Roberts
7
Während dies funktioniert, habe ich begonnen, Object.defineProperty(func, 'name', {value: name})meinen eigenen Code zu verwenden, da ich denke, dass er vielleicht etwas natürlicher und verständlicher ist.
Kybernetikos
funktioniert es mit transpiliertem Code? (Babel oder Typoskript-Ausgaben)
Hitmands
3
Beantwortung meiner eigenen Frage: Ist {[expr]: val}ein Objektinitialisierer (wie auch ein JSON-Objekt), in dem exprsich ein Ausdruck befindet. Was auch immer es auswertet, ist der Schlüssel. {myFn (..){..} }ist eine Abkürzung für {myFn: function myFn(..){..} }. Beachten Sie, dass function myFn(..) {..}ein Ausdruck wie eine anonyme Funktion verwendet werden kann und nur myFneinen Namen hat. Der letzte [name]ist nur der Zugriff auf das Mitglied des Objekts (genau wie obj.keyoder obj['key']). ...ist der Spread-Operator. (Hauptquelle: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… )
Jason Young
1
Danke für deine Absicht! Hinweis: Der Wert von wird dadurch nicht beibehalten this. Zum Beispiel obj={x:7,getX(){return this.x}}; obj.getX=nameFunction('name',obj.getX); obj.getX();wird nicht funktionieren. Sie können Ihre Antwort bearbeiten und function nameFunction(name, body) { return {[name](...args) {return body.apply(this, args)}}[name] }stattdessen verwenden!
TS
10

Ich denke, die meisten Vorschläge hier sind suboptimal, indem evale, hackige Lösungen oder Wrapper verwendet werden. Ab ES2015 werden Namen aus der syntaktischen Position für Variablen und Eigenschaften abgeleitet.

Das wird also gut funktionieren:

const name = 'myFn';
const fn = {[name]: function() {}}[name];
fn.name // 'myFn'

Widerstehen Sie der Versuchung, benannte Funktionsfactory-Methoden zu erstellen, da Sie die Funktion nicht von außen übergeben und an der syntaktischen Position nachrüsten können, um auf ihren Namen zu schließen. Dann ist es schon zu spät. Wenn Sie das wirklich brauchen, müssen Sie einen Wrapper erstellen. Jemand hat das hier gemacht, aber diese Lösung funktioniert nicht für Klassen (die auch Funktionen sind).

Eine ausführlichere Antwort mit allen beschriebenen Varianten wurde hier geschrieben: https://stackoverflow.com/a/9479081/633921

Albin
quelle
1
Wie verbessert diese Antwort stackoverflow.com/a/41854075/3966682 ?
d4nyll
@ d4nyll Ich habe bereits geantwortet: Es wird ein Wrapper erstellt, der zustandsbehaftete Funktionen (Funktionen, die "this" verwenden), auch bekannt als Klassen, unterbricht.
Albin
@ Albin FWIW, mir ist überhaupt nicht klar, wie deine Antwort das sagt. In jedem Fall ist das gut zu wissen.
Jason Young
@JasonYoung "Widerstehen Sie der Versuchung, Factory-Methoden für benannte Funktionen zu erstellen, da Sie die Funktion nicht von außen übergeben und in die syntaktische Position nachrüsten können, um auf ihren Namen zu schließen. Dann ist es bereits zu spät. Wenn Sie das wirklich brauchen, sind Sie es muss hier einen Wrapper erstellen. Jemand hat das hier getan, aber diese Lösung funktioniert nicht für Klassen (die auch Funktionen sind). "
Albin
3

Die Syntax function[i](){}impliziert ein Objekt mit Eigenschaftswerten, bei denen es sich um Funktionen handelt function[], die durch den Namen indiziert sind [i].
Also
{"f:1":function(){}, "f:2":function(){}, "f:A":function(){}, ... } ["f:"+i].

{"f:1":function f1(){}, "f:2":function f2(){}, "f:A":function fA(){}} ["f:"+i]behält die Identifizierung des Funktionsnamens bei. Siehe Anmerkungen unten bezüglich: .

So,

javascript: alert(
  new function(a){
    this.f={"instance:1":function(){}, "instance:A":function(){}} ["instance:"+a]
  }("A") . toSource()
);

wird ({f:(function () {})})in FireFox angezeigt.
(Dies ist fast die gleiche Idee wie bei dieser Lösung , nur dass ein generisches Objekt verwendet wird und das Fensterobjekt nicht mehr direkt mit den Funktionen gefüllt wird.)

Diese Methode füllt die Umgebung explizit mit instance:x.

javascript: alert(
  new function(a){
    this.f=eval("instance:"+a+"="+function(){})
  }("A") . toSource()
);
alert(eval("instance:A"));

Anzeigen

({f:(function () {})})

und

function () {
}

Obwohl die Eigenschaftsfunktion fauf ein anonymous functionund nicht verweist instance:x, vermeidet diese Methode mehrere Probleme mit dieser Lösung .

javascript: alert(
  new function(a){
    eval("this.f=function instance"+a+"(){}")
  }("A") . toSource()
);
alert(instanceA);    /* is undefined outside the object context */

wird nur angezeigt

({f:(function instanceA() {})})
  • Das Embedded :macht das Javascriptfunction instance:a(){} ungültig.
  • Anstelle einer Referenz wird die tatsächliche Textdefinition der Funktion von analysiert und interpretiert eval.

Das Folgende ist nicht unbedingt problematisch,

  • Die instanceAFunktion steht nicht direkt zur Verfügung alsinstanceA()

und ist daher viel konsistenter mit dem ursprünglichen Problemkontext.

Angesichts dieser Überlegungen

this.f = {"instance:1": function instance1(){},
          "instance:2": function instance2(){},
          "instance:A": function instanceA(){},
          "instance:Z": function instanceZ(){}
         } [ "instance:" + a ]

pflegt die globale Computerumgebung so weit wie möglich mit der Semantik und Syntax des OP-Beispiels.

Ekim
quelle
Diese Auflösung funktioniert nur für statische Namen oder für dynamische ES6-Eigenschaftsnamen. Zum Beispiel (name => ({[name]:function(){}})[name])('test')funktioniert, (name => {var x={}; x[name] = function(){}; return x[name];})('test')aber nicht
William Leung
3

Die am häufigsten gewählte Antwort hat bereits den Funktionskörper [String] definiert. Ich suchte nach einer Lösung, um den Namen der bereits deklarierten Funktion umzubenennen, und schließlich habe ich mich nach einer Stunde des Kampfes damit befasst. Es:

  • übernimmt die bereits deklarierte Funktion
  • analysiert es mit der .toString()Methode in [String]
  • überschreibt dann den Namen (der benannten Funktion) oder hängt den neuen (wenn anonym) zwischen functionund an(
  • Anschließend wird die neu umbenannte Funktion mit dem new Function()Konstruktor erstellt

function nameAppender(name,fun){
  const reg = /^(function)(?:\s*|\s+([A-Za-z0-9_$]+)\s*)(\()/;
  return (new Function(`return ${fun.toString().replace(reg,`$1 ${name}$3`)}`))();
}

//WORK FOR ALREADY NAMED FUNCTIONS:
function hello(name){
  console.log('hello ' + name);
}

//rename the 'hello' function
var greeting = nameAppender('Greeting', hello); 

console.log(greeting); //function Greeting(name){...}


//WORK FOR ANONYMOUS FUNCTIONS:
//give the name for the anonymous function
var count = nameAppender('Count',function(x,y){ 
  this.x = x;
  this.y = y;
  this.area = x*y;
}); 

console.log(count); //function Count(x,y){...}

Paweł
quelle
Funktioniert im Gegensatz zu einigen anderen hier. Sie verdienen mehr Upvotes.
Kiara Grouwstra
Genau! Funktioniert perfekt für meinen Zweck. (unter Verwendung dynamisch benannter Funktionen als Konstruktoren)
Falk
2

Wie wäre es mit

this.f = window["instance:" + a] = function(){};

Der einzige Nachteil ist, dass die Funktion in ihrer toSource-Methode keinen Namen angibt. Das ist normalerweise nur ein Problem für Debugger.

entonio
quelle
Das ist nicht gut, denn der einzige Grund, den ich brauche, ist, den Namen der Klassen schneller zu sehen. Jede Klasse in meinem System ist eine anonyme Funktion und zeigt mir im Debugger anonym ..
Totty.js
1
Na dann hättest du das in der Frage sagen können.
Entonio
2

Dynamische Methoden eines Objekts können mit den von ECMAScript 2015 (ES6) bereitgestellten Object Literal Extensions erstellt werden:

const postfixes = ['foo', 'bar'];

const mainObj = {};

const makeDynamic = (postfix) => {
  const newMethodName = 'instance: ' + postfix;
  const tempObj = {
    [newMethodName]() {
      console.log(`called method ${newMethodName}`);
    }
  }
  Object.assign(mainObj, tempObj);
  return mainObj[newMethodName]();
}

const processPostfixes = (postfixes) => { 
  for (const postfix of postfixes) {
    makeDynamic(postfix); 
  }
};

processPostfixes(postfixes);

console.log(mainObj);

Die Ausgabe des obigen Codes lautet:

"called method instance: foo"
"called method instance: bar"
Object {
  "instance: bar": [Function anonymous],
  "instance: foo": [Function anonymous]
}
Luke Schoen
quelle
Dies ist eher vergleichbar mit: o={}; o[name]=(()=>{})anstattfunction <<name>>(){}
Sancarn
2

So legen Sie den Namen einer vorhandenen anonymen Funktion fest:
(Basierend auf der Antwort von @ Marcosc)

var anonymous = function() { return true; }

var name = 'someName';
var strFn = anonymous.toString().replace('function ', 'return function ' + name);
var fn = new Function(strFn)();

console.log(fn()); // —> true

Demo .

Hinweis : Tu es nicht; /

Onur Yıldırım
quelle
Wenn Sie abstimmen, ist es in Ordnung. Aber Sie sollten die Höflichkeit Ihrer Argumentation geben, damit wir von Ihnen lernen können. OP fragt nach "dynamischen" Funktionsnamen. Dies ist eine Möglichkeit, dies zu tun, aber ich würde es niemals empfehlen oder jemals tun.
Onur Yıldırım
1

Es gibt zwei Methoden, um dies zu erreichen, und sie haben ihre Vor- und Nachteile.


name Eigenschaftsdefinition

Definieren unveränderliche name Eigenschaft einer Funktion.

Vorteile

  • Jedes Zeichen ist für den Namen verfügbar. (zB () 全 {}/1/얏호/ :D #GO(@*#%! /*)

Nachteile

  • Der syntaktische ("expressionale") Name der Funktion entspricht möglicherweise nicht ihrem nameEigenschaftswert.

Bewertung des Funktionsausdrucks

Einen Namen Funktion Ausdruck und Auswertung mit FunctionKonstruktor.

Vorteile

  • Der syntaktische ("expressionale") Name der Funktion entspricht immer ihrem nameEigenschaftswert.

Nachteile

  • Leerzeichen (und usw.) sind für den Namen nicht verfügbar.
  • Expression-injizierbare (zB. Für die Eingabe (){}/1//der Ausdruck ist return function (){}/1//() {}, gibt NaNstatt einer Funktion.).

const demoeval = expr => (new Function(`return ${expr}`))();

// `name` property definition
const method1 = func_name => {
    const anon_func = function() {};
    Object.defineProperty(anon_func, "name", {value: func_name, writable: false});
    return anon_func;
};

const test11 = method1("DEF_PROP"); // No whitespace
console.log("DEF_PROP?", test11.name); // "DEF_PROP"
console.log("DEF_PROP?", demoeval(test11.toString()).name); // ""

const test12 = method1("DEF PROP"); // Whitespace
console.log("DEF PROP?", test12.name); // "DEF PROP"
console.log("DEF PROP?", demoeval(test12.toString()).name); // ""

// Function expression evaluation
const method2 = func_name => demoeval(`function ${func_name}() {}`);

const test21 = method2("EVAL_EXPR"); // No whitespace
console.log("EVAL_EXPR?", test21.name); // "EVAL_EXPR"
console.log("EVAL_EXPR?", demoeval(test21.toString()).name); // "EVAL_EXPR"

const test22 = method2("EVAL EXPR"); // Uncaught SyntaxError: Unexpected identifier
Константин Ван
quelle
1

Wenn Sie eine dynamische Funktion wie die __callFunktion in PHP haben möchten , können Sie Proxies verwenden.

const target = {};

const handler = {
  get: function (target, name) {
    return (myArg) => {
      return new Promise(resolve => setTimeout(() => resolve('some' + myArg), 600))
    }
  }
};

const proxy = new Proxy(target, handler);

(async function() {
  const result = await proxy.foo('string')
  console.log('result', result) // 'result somestring' after 600 ms
})()
bla bla bla
quelle
1

Sie können den Namen der dynamischen Funktion und solche Parameter verwenden.

1) Funktion Separate definieren und aufrufen

let functionName = "testFunction";
let param = {"param1":1 , "param2":2};

var func = new Function(
   "return " + functionName 
)();

func(param);

function testFunction(params){
   alert(params.param1);
}

2) Funktionscode dynamisch definieren

let functionName = "testFunction(params)";
let param = {"param1":"1" , "param2":"2"};
let functionBody = "{ alert(params.param1)}";

var func = new Function(
    "return function " + functionName + functionBody 
)();

func(param);
Manuja Jayawardana
quelle
0

Vielen Dank, Marcosc! Wenn Sie auf seiner Antwort aufbauen und eine Funktion umbenennen möchten, verwenden Sie Folgendes :

// returns the function named with the passed name
function namedFunction(name, fn) {
    return new Function('fn',
        "return function " + name + "(){ return fn.apply(this,arguments)}"
    )(fn)
}
BT
quelle
0

Diese Dienstprogrammfunktion führt mehrere Funktionen zu einer zusammen (unter Verwendung eines benutzerdefinierten Namens). Die einzige Voraussetzung ist, dass die bereitgestellten Funktionen zu Beginn und am Ende des Bereichs ordnungsgemäß "neu gezeichnet" werden.

const createFn = function(name, functions, strict=false) {

    var cr = `\n`, a = [ 'return function ' + name + '(p) {' ];

    for(var i=0, j=functions.length; i<j; i++) {
        var str = functions[i].toString();
        var s = str.indexOf(cr) + 1;
        a.push(str.substr(s, str.lastIndexOf(cr) - s));
    }
    if(strict == true) {
        a.unshift('\"use strict\";' + cr)
    }
    return new Function(a.join(cr) + cr + '}')();
}

// test
var a = function(p) {
    console.log("this is from a");
}
var b = function(p) {
    console.log("this is from b");
}
var c = function(p) {
    console.log("p == " + p);
}

var abc = createFn('aGreatName', [a,b,c])

console.log(abc) // output: function aGreatName()

abc(123)

// output
this is from a
this is from b
p == 123
MetalGodwin
quelle
0

Ich hatte besseres Glück, Darrens Antwort und Kyernetikos 'Antwort zu kombinieren .

const nameFunction = function (fn, name) {
  return Object.defineProperty(fn, 'name', {value: name, configurable: true});
};

/* __________________________________________________________________________ */

let myFunc = function oldName () {};

console.log(myFunc.name); // oldName

myFunc = nameFunction(myFunc, 'newName');

console.log(myFunc.name); // newName

Hinweis: configurablewird auf truedie Standard - ES2015 - Spezifikation für Function.name passen 1

Dies vor allem dazu beigetragen , in immer einen Fehler in Webpack ähnlich wie um diesen .

Update: Ich habe darüber nachgedacht, dies als npm-Paket zu veröffentlichen, aber dieses Paket von sindresorhus macht genau das Gleiche.

  1. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name
Scott Rüdiger
quelle
0

Ich hatte viel mit diesem Problem zu kämpfen. Die @ Albin-Lösung funktionierte während der Entwicklung wie ein Zauber, aber sie funktionierte nicht, als ich sie auf Produktion umstellte. Nach einigem Debuggen wurde mir klar, wie ich das erreichen konnte, was ich brauchte. Ich verwende ES6 mit CRA (Create-React-App), was bedeutet, dass es von Webpack gebündelt wird.

Nehmen wir an, Sie haben eine Datei, die die Funktionen exportiert, die Sie benötigen:

myFunctions.js

export function setItem(params) {
  // ...
}

export function setUser(params) {
  // ...
}

export function setPost(params) {
  // ...
}

export function setReply(params) {
  // ...
}

Und Sie müssen diese Funktionen an anderer Stelle dynamisch aufrufen:

myApiCalls.js

import * as myFunctions from 'path_to/myFunctions';
/* note that myFunctions is imported as an array,
 * which means its elements can be easily accessed
 * using an index. You can console.log(myFunctions).
 */

function accessMyFunctions(res) {
  // lets say it receives an API response
  if (res.status === 200 && res.data) {
    const { data } = res;
    // I want to read all properties in data object and 
    // call a function based on properties names.
    for (const key in data) {
      if (data.hasOwnProperty(key)) {
        // you can skip some properties that are usually embedded in
        // a normal response
        if (key !== 'success' && key !== 'msg') {
          // I'm using a function to capitalize the key, which is
          // used to dynamically create the function's name I need.
          // Note that it does not create the function, it's just a
          // way to access the desired index on myFunctions array.
          const name = `set${capitalizeFirstLetter(key)}`;
          // surround it with try/catch, otherwise all unexpected properties in
          // data object will break your code.
          try {
            // finally, use it.
            myFunctions[name](data[key]);
          } catch (error) {
            console.log(name, 'does not exist');
            console.log(error);
          }
        }
      }
    }
  }
}
Rodrigo M.
quelle
0

Am besten erstellen Sie ein Objekt mit einer Liste dynamischer Funktionen wie:

const USER = 'user';

const userModule = {
  [USER + 'Action'] : function () { ... }, 
  [USER + 'OnClickHandler'] : function () { ... }, 
  [USER + 'OnCreateHook'] : function () { ... }, 
}
alex dykyі
quelle
-1
function myFunction() {
    console.log('It works!');
}

var name = 'myFunction';

window[name].call();
Danilo Colasso
quelle
-2

Ich vermisse hier vielleicht das Offensichtliche, aber was ist falsch daran, nur den Namen hinzuzufügen? Funktionen werden unabhängig von ihrem Namen aufgerufen. Namen werden nur aus Gründen des Geltungsbereichs verwendet. Wenn Sie es einer Variablen zuweisen und es sich im Gültigkeitsbereich befindet, kann es aufgerufen werden. Was passiert, ist, dass Sie eine Variable ausführen, die zufällig eine Funktion ist. Wenn Sie beim Debuggen aus Identifikationsgründen einen Namen haben müssen, fügen Sie ihn zwischen der Schlüsselwortfunktion und der öffnenden Klammer ein.

var namedFunction = function namedFunction (a,b) {return a+b};

alert(namedFunction(1,2));
alert(namedFunction.name);
alert(namedFunction.toString());

Ein alternativer Ansatz besteht darin, die Funktion in einen äußeren umbenannten Shim zu verpacken, den Sie auch in einen äußeren Wrapper übergeben können, wenn Sie den umgebenden Namespace nicht verschmutzen möchten. Wenn Sie die Funktion tatsächlich dynamisch aus Zeichenfolgen erstellen möchten (was in den meisten dieser Beispiele der Fall ist), ist es trivial, die Quelle umzubenennen, um das zu tun, was Sie möchten. Wenn Sie jedoch vorhandene Funktionen umbenennen möchten, ohne deren Funktionalität zu beeinträchtigen, wenn Sie an anderer Stelle aufgerufen werden, ist ein Shim der einzige Weg, dies zu erreichen.

(function(renamedFunction) {

  alert(renamedFunction(1,2));
  alert(renamedFunction.name);
  alert(renamedFunction.toString());
  alert(renamedFunction.apply(this,[1,2]));


})(function renamedFunction(){return namedFunction.apply(this,arguments);});

function namedFunction(a,b){return a+b};

das ist Französisch
quelle
Funktion / Methode nameist nützlich, da sie jetzt aus Variablen und Eigenschaften abgeleitet wird. Es wird auch in Stapelspuren verwendet. Bsp var fn = function(){}; console.log(fn.name). Es ist unveränderlich, so dass Sie es später nicht ändern können. Wenn Sie eine Factory-Methode schreiben, die alle Funktionen benennt, fnwird das Debuggen dadurch schwieriger.
Albin
-3

Sie waren in der Nähe:

this["instance_" + a] = function () {...};

{...};

berge
quelle
-9

Dies ist die beste Lösung, besser dann new Function('return function name(){}')().

Eval ist die schnellste Lösung:

Geben Sie hier die Bildbeschreibung ein

var name = 'FuncName'
var func = eval("(function " + name + "(){})")
Maxmaxmaximus
quelle
Jeder, der dies liest, folgt, folge, folge dieser Antwort.
Maxmaxmaximus
1
@majidarif der Typ ist korrekt, es ist am schnellsten: jsperf.com/dynamicfunctionnames/1 . Ist bei weitem nicht die sicherste.
Sancarn