Dynamiczna nazwa funkcji w javascript?

89

Mam to:

this.f = function instance(){};

Chciałbym to mieć:

this.f = function ["instance:" + a](){};
Totty.js
źródło
10
Nie możesz. Ale możesz miećthis["instance"] = function() { }
Raynos
Aby wyjaśnić, co mówił Raynos, możesz zrobić this["instance" + a] = function() { }. To nie było dla mnie jasne.
Andrew,

Odpowiedzi:

8

aktualizacja

Jak wspominali inni, nie jest to najszybsze ani najbardziej zalecane rozwiązanie. Rozwiązanie Marcosc poniżej jest drogą do zrobienia.

Możesz użyć eval:

var code = "this.f = function " + instance + "() {...}";
eval(code);
Mo Valipour
źródło
1
o to właśnie prosiłem, dzięki! (w każdym razie nie
użyję
3
Wiem, że o to prosił OP, ale to okropny pomysł. To, że możesz, nie oznacza, że ​​powinieneś zrobić coś takiego. Istnieją znacznie lepsze alternatywy, które są prawie identyczne pod względem funkcjonalności.
Thomas Eding
4
@ sg3s: czy możesz zaproponować inne rozwiązanie?
Tom
2
@ sg3s: Dziękuję za odpowiedź na mój komentarz! Pozwólcie, że wyjaśnię, o co mi chodziło i o co właściwie chcę zapytać: czy rozwiązanie Marcosc naprawdę różni się znacząco od eval? Czy to naprawdę robi różnicę, jeśli coś ewaluujesz lub podajesz do konstruktora funkcji? Jeśli tak, czy możesz wyjaśnić różnicę i jej konsekwencje? Dzięki!
Tom
5
@Tom Dla przyszłych czytelników: to rozwiązanie nie różni się zbytnio od odpowiedzi Marcosc, obaj używają eval()( Functionkonstruktor robi to w środku).
kapa
128

Zasadniczo zrobi to na najprostszym poziomie:

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

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

Jeśli chcesz uzyskać więcej fantazji, napisałem artykuł na temat „ Dynamiczne nazwy funkcji w JavaScript ”.

Marcosc
źródło
Dobra robota! Właśnie odkryłem to sam i miałem zamiar opublikować to na jednym z tych pytań, ale mnie pokonałeś. Ostatnio dużo pracowałem z backbone.js i jestem zmęczony widzeniem „dziecka” wszędzie w moim debugerze Chrome. To rozwiązuje ten problem. Zastanawiam się, czy są jakieś implikacje dla wydajności, takie jak używanie eval.
webXL
Ma to również wpływ na bezpieczeństwo. Otrzymuję informację „Konstruktor funkcji jest eval” z jsHint, więc opakowuję to w sprawdzenie trybu debugowania, ponieważ jest to jedyny powód, aby tego używać. Wydaje mi się, że „użyj ścisłego” zapobiegnie wszelkim błędom w obiekcie globalnym, ale wszelkie argumenty konstruktora Function mogą być modyfikowane i cokolwiek „this” jest ustawione.
webXL
Tak, to w ekstremalnych sytuacjach, w których musisz zbudować coś w locie.
Marcosc,
1
Szczerze uważam, że stackoverflow.com/a/40918734/2911851 jest lepszym rozwiązaniem, nie ma potrzeby dołączania treści funkcji jako ciągu (chyba, że ​​czegoś mi brakuje, ale po prostu próbowałem i działałem świetnie).
Gian Franco Zabarino
2
AirBnB zdecydowanie odradza to , ponieważ konstruktor funkcji użyje evaldo oceny javascript - otwierając w ten sposób kod na mnóstwo luk w zabezpieczeniach.
Philippe Hebert
43

Możesz użyć Object.defineProperty, jak wspomniano w dokumentacji MDN JavaScript [1]:

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
źródło
2
Wygląda na to, że ustawia to właściwość name zgodnie z przeznaczeniem, ale jeśli zaloguję się do funkcji w mojej przeglądarce (najnowsza edycja Firefoksa) function fn(), fnzostanie ona wydrukowana , będąc oryginalną nazwą. Dziwne.
Kiara Grouwstra
ten sam komentarz w Google Chrome Evergreen. Właściwość jest poprawnie ustawiona, ale nazwa w konsoli to oryginalna nazwa funkcji. Por. 2ality.com/2015/09/… Wygląda na to, że nazwa funkcji jest przypisana podczas tworzenia i nie można jej zmienić?
user3743222
Na tej stronie 2ality.com zobacz następny akapit „Zmiana nazwy funkcji” [1], który opisuje tę samą technikę, którą można znaleźć w dokumentacji MDN Javascript Reference. 1. 2ality.com/2015/09/…
Darren
36

W najnowszych silnikach możesz to zrobić

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
źródło
1
Po spędzeniu godzin na szukaniu rozwiązania, nawet nie pomyślałem o użyciu obiektu z wyliczoną nazwą właściwości. Dokładnie to, czego potrzebowałem. Dzięki!
Levi Roberts
7
Chociaż to działa, zacząłem używać go Object.defineProperty(func, 'name', {value: name})we własnym kodzie, ponieważ myślę, że jest to trochę bardziej naturalne i zrozumiałe.
kybernetikos
czy to działa z transpiled kodem? (Wyjścia Babel lub maszynopisu)
Hitmands
3
Odpowiadając na moje własne pytanie: {[expr]: val}jest inicjatorem obiektu (tak jak obiekt JSON), gdzie exprjest jakieś wyrażenie; cokolwiek to ocenia, jest kluczem. {myFn (..){..} }jest skrótem od {myFn: function myFn(..){..} }. Zauważ, że function myFn(..) {..}może być używane jako wyrażenie, tak jak funkcja anonimowa, tylko myFnmiałaby nazwę. Ostatnim [name]jest po prostu uzyskanie dostępu do elementu członkowskiego obiektu (podobnie jak obj.keylub obj['key']). ...jest operatorem spreadu. (Główne źródło: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… )
Jason Young
1
Dziękuję za rozwiązanie! Uwaga: nie zachowuje to wartości this. Na przykład obj={x:7,getX(){return this.x}}; obj.getX=nameFunction('name',obj.getX); obj.getX();nie zadziała. Możesz edytować swoją odpowiedź i użyć function nameFunction(name, body) { return {[name](...args) {return body.apply(this, args)}}[name] }zamiast tego!
TS
11

Myślę, że większość sugestii tutaj jest nieoptymalna, przy użyciu eval, hackerskich rozwiązań lub opakowań. Począwszy od ES2015 nazwy są wywnioskowane z pozycji składniowej dla zmiennych i właściwości.

Więc to zadziała dobrze:

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

Oprzyj się pokusie tworzenia nazwanych metod fabryki funkcji, ponieważ nie byłbyś w stanie przekazać funkcji z zewnątrz i przekształcić ją w pozycję składniową, aby wywnioskować jej nazwę. Wtedy jest już za późno. Jeśli naprawdę tego potrzebujesz, musisz utworzyć opakowanie. Ktoś to zrobił tutaj, ale to rozwiązanie nie działa dla klas (które są również funkcjami).

O wiele bardziej dogłębna odpowiedź ze wszystkimi przedstawionymi wariantami została napisana tutaj: https://stackoverflow.com/a/9479081/633921

Albin
źródło
1
W jaki sposób ta odpowiedź poprawia stackoverflow.com/a/41854075/3966682 ?
d4nyll
1
@ d4nyll Odpowiedziałem już, że: Tworzy opakowanie, które łamie funkcje stanowe (funkcje używające "this") aka klas.
Albin,
@Albin FWIW, wcale nie jest dla mnie jasne, jak mówi to twoja odpowiedź. Tak czy inaczej, dobrze to wiedzieć.
Jason Young
@JasonYoung "Oprzyj się pokusie tworzenia nazwanych metod fabryki funkcji, ponieważ nie byłbyś w stanie przekazać funkcji z zewnątrz i zmodernizować ją do pozycji składniowej, aby wywnioskować jej nazwę. Wtedy jest już za późno. Jeśli naprawdę tego potrzebujesz, trzeba utworzyć opakowanie. Ktoś to zrobił tutaj, ale to rozwiązanie nie działa dla klas (które są również funkcjami). "
Albin
3

Co powiesz na

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

Jedyną wadą jest to, że funkcja w swojej metodzie toSource nie wskazywałaby nazwy. Zwykle jest to problem tylko dla debuggerów.

entonio
źródło
to nie jest dobre, ponieważ jedynym powodem, dla którego potrzebuję, jest szybsze zobaczenie nazw klas. Każda klasa w moim systemie jest funkcją anonimową, aw debugerze pokazuje mi anonimowość ..
Totty.js
1
No cóż, mógłbyś to powiedzieć w pytaniu.
entonio
3

Składnia function[i](){}oznacza obiekt z wartości nieruchomości, które są funkcje, function[], indeksowane przez nazwy [i].
Tak więc
{"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]zachowa identyfikację nazwy funkcji. Zobacz uwagi poniżej dotyczące :.

Więc,

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

wyświetla się ({f:(function () {})})w FireFox.
(To jest prawie taki sam pomysł jak to rozwiązanie , tyle że używa ogólnego obiektu i nie wypełnia już bezpośrednio obiektu okna funkcjami).

Ta metoda jawnie wypełnia środowisko instance:x.

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

wyświetlacze

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

i

function () {
}

Chociaż funkcja właściwości fodwołuje się do anonymous functioni nie instance:x, ta metoda pozwala uniknąć kilku problemów związanych z tym rozwiązaniem .

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

wyświetla tylko

({f:(function instanceA() {})})
  • Osadzony :sprawia, że ​​javascript jest function instance:a(){}nieprawidłowy.
  • Zamiast odwołania, rzeczywista definicja tekstu funkcji jest analizowana i interpretowana przez eval.

Poniższe niekoniecznie są problematyczne,

  • Ta instanceAfunkcja nie jest bezpośrednio dostępna do użycia jakoinstanceA()

a więc jest znacznie bardziej spójny z pierwotnym kontekstem problemu.

Biorąc pod uwagę te względy,

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

utrzymuje globalne środowisko obliczeniowe z semantyką i składnią przykładu OP w jak największym stopniu.

Ekim
źródło
To rozwiązanie działa tylko w przypadku nazw statycznych lub dynamicznych nazw właściwości ES6. Na przykład (name => ({[name]:function(){}})[name])('test')działa, ale (name => {var x={}; x[name] = function(){}; return x[name];})('test')nie
William Leung
3

Najczęściej głosowana odpowiedź ma już zdefiniowaną treść funkcji [String]. Szukałem rozwiązania, żeby zmienić nazwę już zadeklarowanej funkcji i ostatecznie po godzinie zmagań się z tym uporałem. To:

  • przyjmuje funkcję zadeklarowaną przez alredy
  • analizuje go do [String] za pomocą .toString()metody
  • następnie nadpisuje nazwę (nazwanej funkcji) lub dodaje nową (gdy jest anonimowa) między functiona(
  • następnie tworzy nową funkcję o zmienionej nazwie z new Function()konstruktorem

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ł
źródło
2

Dynamiczne metody obiektu mogą być tworzone przy użyciu rozszerzeń literałów obiektu dostarczonych przez ECMAScript 2015 (ES6):

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);

Wynik uruchomienia powyższego kodu to:

"called method instance: foo"
"called method instance: bar"
Object {
  "instance: bar": [Function anonymous],
  "instance: foo": [Function anonymous]
}
Luke Schoen
źródło
jest to bardziej podobne do: o={}; o[name]=(()=>{})zamiastfunction <<name>>(){}
Sancarn
2

Aby ustawić nazwę istniejącej funkcji anonimowej:
(Na podstawie odpowiedzi @ 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 .

Uwaga : nie rób tego; /

Onur Yıldırım
źródło
Kiedy głosujesz przeciw, wszystko jest w porządku. Ale powinieneś dać uprzejmość swojego rozumowania, abyśmy mogli się od ciebie nauczyć. OP pyta o „dynamiczne” nazwy funkcji. To jeden ze sposobów, ale nigdy bym tego nie polecał, ani nigdy tego nie robiłem.
Onur Yıldırım
1

Są na to dwie metody i mają one swoje wady i zalety.


name definicja właściwości

Definiowanie niezmiennej name właściwości funkcji.

Plusy

  • Każda postać jest dostępna dla nazwy. (np. () 全 {}/1/얏호/ :D #GO(@*#%! /*)

Cons

  • Nazwa syntaktyczna („wyrażona”) funkcji może nie odpowiadać namewartości jej właściwości.

Ocena wyrażeń funkcyjnych

Tworzenie nazwanego wyrażenia funkcyjnego i obliczanie go za pomocą Functionkonstruktora.

Plusy

  • Nazwa syntaktyczna („wyrażona”) funkcji zawsze odpowiada namewartości jej właściwości.

Cons

  • W nazwie nie są dostępne odstępy (itp.).
  • Możliwość wstrzyknięcia wyrażenia (np. Na wejściu (){}/1//wyrażenie to return function (){}/1//() {}daje NaNzamiast funkcji).

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
Константин Ван
źródło
1

Jeśli chcesz mieć funkcję dynamiczną, taką jak __callfunkcja w PHP, możesz użyć proxy.

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
})()
blablabla
źródło
1

Możesz użyć dynamicznej nazwy funkcji i takich parametrów.

1) Zdefiniuj funkcję Separate i nazwij ją

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

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

func(param);

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

2) Zdefiniuj dynamiczny kod funkcji

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
źródło
0

Dziękuję Marcosc! Opierając się na jego odpowiedzi, jeśli chcesz zmienić nazwę dowolnej funkcji, użyj tego:

// 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
źródło
0

Ta funkcja narzędziowa łączy wiele funkcji w jedną (używając niestandardowej nazwy). Jedynym wymaganiem jest, aby dostarczane funkcje były odpowiednio „nowe” na początku i na końcu zakresu.

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
źródło
0

Miałem więcej szczęścia w łączeniu odpowiedzi Darrena i odpowiedź kyernetikos męska .

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

Uwaga: configurablejest ustawiony na truezgodność ze standardową specyfikacją ES2015 dla Function.name 1

To szczególnie pomogło w obejściu błędu w Webpack, podobnego do tego .

Aktualizacja: myślałem o opublikowaniu tego jako pakietu npm, ale ten pakiet od sindresorhus robi dokładnie to samo.

  1. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name
Scott Rudiger
źródło
0

Bardzo walczyłem z tym problemem. Rozwiązanie @Albin działało jak urok podczas wywoływania, ale nie działało, gdy przestawiałem je na produkcję. Po pewnym debugowaniu zdałem sobie sprawę, jak osiągnąć to, czego potrzebowałem. Używam ES6 z CRA (aplikacja do tworzenia reakcji), co oznacza, że ​​jest dołączany do pakietu Webpack.

Powiedzmy, że masz plik, który eksportuje potrzebne funkcje:

myFunctions.js

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

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

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

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

I musisz dynamicznie wywoływać te funkcje w innym miejscu:

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.
źródło
0

najlepiej stworzyć obiekt z listą dynamicznych funkcji takich jak:

const USER = 'user';

const userModule = {
  [USER + 'Action'] : function () { ... }, 
  [USER + 'OnClickHandler'] : function () { ... }, 
  [USER + 'OnCreateHook'] : function () { ... }, 
}
аlex dykyі
źródło
-1
function myFunction() {
    console.log('It works!');
}

var name = 'myFunction';

window[name].call();
Danilo Colasso
źródło
-2

Być może brakuje mi tego, co oczywiste, ale co jest złego w samym dodaniu nazwy? funkcje są wywoływane niezależnie od ich nazwy. nazwy są używane tylko do celów określania zakresu. jeśli przypiszesz go do zmiennej i znajduje się w zakresie, można ją wywołać. zdarza się, że wykonujesz zmienną, która jest funkcją. jeśli musisz mieć nazwę dla celów identyfikacji podczas debugowania, wstaw ją między słowem kluczowym funkcja a nawiasem otwierającym.

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

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

alternatywnym podejściem jest umieszczenie funkcji w zewnętrznej podkładce o zmienionej nazwie, którą można również przekazać do zewnętrznego opakowania, jeśli nie chcesz brudzić otaczającej przestrzeni nazw. jeśli chcesz faktycznie dynamicznie tworzyć funkcję z łańcuchów (co robi większość z tych przykładów), zmiana nazwy źródła, aby robić to, co chcesz, jest trywialna. jeśli jednak chcesz zmienić nazwy istniejących funkcji bez wpływu na ich funkcjonalność, gdy są wywoływane w innym miejscu, jedynym sposobem na osiągnięcie tego jest podkładka.

(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};

cestmoi
źródło
Funkcja / metoda namejest przydatna, ponieważ jest teraz wywnioskowana ze zmiennej i właściwości. Jest również używany w śladach stosu. Np var fn = function(){}; console.log(fn.name). Jest niezmienny, więc nie możesz go później zmienić. Jeśli napiszesz metodę fabryczną, która nazywa wszystkie funkcje fn, utrudni to debugowanie.
Albin,
-3

Byłeś blisko:

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

{...};

berge
źródło
-9

To NAJLEPSZE rozwiązanie, więc lepiej new Function('return function name(){}')().

Eval to najszybsze rozwiązanie:

wprowadź opis obrazu tutaj

var name = 'FuncName'
var func = eval("(function " + name + "(){})")
Maxmaxmaximus
źródło
Każdy, kto to czyta, postępuj zgodnie z tą odpowiedzią.
Maxmaxmaximus
1
@majidarjeśli facet ma rację, jest najszybszy: jsperf.com/dynamicfunctionnames/1 . Jednak zdecydowanie nie jest najbezpieczniejszy.
Sancarn