So führen Sie eine JavaScript-Funktion aus, wenn ich ihren Namen als Zeichenfolge habe


1050

Ich habe den Namen einer Funktion in JavaScript als Zeichenfolge. Wie konvertiere ich das in einen Funktionszeiger, damit ich ihn später aufrufen kann?

Abhängig von den Umständen muss ich möglicherweise auch verschiedene Argumente an die Methode übergeben.

Einige der Funktionen können die Form von haben namespace.namespace.function(args[...]).

Antworten:


1438

Verwenden evalSie es nur , wenn Sie absolut keine andere Wahl haben.

Wie bereits erwähnt, wäre die Verwendung von so etwas der beste Weg, dies zu tun:

window["functionName"](arguments);

Dies funktioniert jedoch nicht mit einer Namespace-Funktion:

window["My.Namespace.functionName"](arguments); // fail

So würden Sie das machen:

window["My"]["Namespace"]["functionName"](arguments); // succeeds

Um dies zu vereinfachen und Flexibilität zu bieten, gibt es hier eine praktische Funktion:

function executeFunctionByName(functionName, context /*, args */) {
  var args = Array.prototype.slice.call(arguments, 2);
  var namespaces = functionName.split(".");
  var func = namespaces.pop();
  for(var i = 0; i < namespaces.length; i++) {
    context = context[namespaces[i]];
  }
  return context[func].apply(context, args);
}

Sie würden es so nennen:

executeFunctionByName("My.Namespace.functionName", window, arguments);

Beachten Sie, dass Sie in einem beliebigen Kontext übergeben können. Dies würde also wie oben beschrieben erfolgen:

executeFunctionByName("Namespace.functionName", My, arguments);

4
Sie wissen, dass Sie nicht das gesamte "func" -Konstrukt benötigen? "context.apply" allein ist in Ordnung
annakata

16
Klar, das weiß ich - aber die Art und Weise, wie ich die Funktion geschrieben habe, bietet denjenigen, die sie lesen, Klarheit, die möglicherweise nicht vollständig verstehen, was gerade passiert. Ich habe diese Funktion geschrieben und festgestellt, dass Leute, die sie lesen, möglicherweise Hilfe benötigen. Ich werde jedoch eine Alternative anbieten, da Sie gefragt haben ...
Jason Bunting

108
Scratch that - der Code ist klar genug und diejenigen, die es wissen, wissen es. Wenn Sie wie ich sind und wissen, was Sie tun, können Sie solche Änderungen einfach selbst vornehmen, wenn Sie diesen Code verwendet haben. Der Stapelüberlauf dient dazu, andere zu unterrichten, und ich denke, mein Code ist für Anfänger leichter zu verstehen. Trotzdem danke!
Jason Bunting

4
Gibt es eine Situation, in der window ["funcName"] undefiniert zurückgibt? Das ist das Problem, das ich gerade habe. Der aufrufende Code und die Funktion werden in zwei separaten js-Dateien definiert. Ich habe versucht, sie derselben Datei hinzuzufügen, aber das machte keinen Unterschied.
Codemonkey

5
Ich denke, hier gibt es ein Problem. Wenn Sie anrufen My.Namespace.functionName(), thiswird auf das My.NamespaceObjekt verwiesen. Aber wenn Sie anrufen executeFunctionByName("My.Namespace.functionName", window), gibt es keine Möglichkeit, sich thisauf dasselbe zu beziehen. Möglicherweise sollte der letzte Namespace als Bereich verwendet werden, oder windowwenn keine Namespaces vorhanden sind. Oder Sie können dem Benutzer erlauben, den Bereich als Argument anzugeben.
JW.

100

Ich dachte nur, ich würde eine leicht veränderte Version von Jason Bunting 'sehr hilfreicher Funktion veröffentlichen .

Erstens habe ich die erste Anweisung vereinfacht, indem ich Slice () einen zweiten Parameter gegeben habe . Die Originalversion funktionierte in allen Browsern außer IE einwandfrei.

Zweitens habe ich ersetzt dies mit Kontext in der return - Anweisung; Andernfalls zeigte dies immer auf das Fenster, wenn die Zielfunktion ausgeführt wurde.

function executeFunctionByName(functionName, context /*, args */) {
    var args = Array.prototype.slice.call(arguments, 2);
    var namespaces = functionName.split(".");
    var func = namespaces.pop();
    for (var i = 0; i < namespaces.length; i++) {
        context = context[namespaces[i]];
    }
    return context[func].apply(context, args);
}

Es wird nicht überprüft, ob "Funktionsname" tatsächlich vorhanden ist.
Crashalot

Ich denke, Macs Antwort wird unterschätzt. Ich bin kein Experte, aber es scheint gut durchdacht und robust.
Martin Hansen Lennox

65

Die Antwort auf diese andere Frage zeigt Ihnen, wie das geht: Javascript-Äquivalent zu Pythons Einheimischen ()?

Grundsätzlich kann man sagen

window["foo"](arg1, arg2);

oder wie viele andere vorgeschlagen haben, können Sie einfach eval verwenden:

eval(fname)(arg1, arg2);

Dies ist jedoch äußerst unsicher, es sei denn, Sie sind sich absolut sicher, was Sie bewerten.


6
Die erste Form ist weitaus vorzuziehen
Annakata

19
Verwenden Sie eval nur als letzten Ausweg, wenn alles andere fehlschlägt.
Jason Bunting

1
Es ist ... aber wird es mit Funktionen wie diesen funktionieren: xyz (args)?
Kieron

@ Keiron: Ja. siehe meine Antwort unten
annakata

55

Könnten Sie das nicht einfach so machen:

var codeToExecute = "My.Namespace.functionName()";
var tmpFunc = new Function(codeToExecute);
tmpFunc();

Mit dieser Methode können Sie auch jedes andere JavaScript ausführen.


3
funktioniert, wenn gerade Argumente mit der Funktion übergeben werden
adeel41

Was ist mit Funktionsrückgabe?
Peter Denev

12
Wie unterscheidet sich das von eval("My.Namespace.functionName()");?
Developerbmw

@ PeterDenev ändern Sie einfach die erste Zeile zuvar codeToExecute = "return My.Namespace.functionName()";
Developerbmw

2
@developerbmw, hier ist Antwort stackoverflow.com/questions/4599857/…
Tejasvi Hegde

48

Ich denke, eine elegante Möglichkeit, dies zu tun, besteht darin, Ihre Funktionen in einem Hash-Objekt zu definieren. Dann können Sie mithilfe der Zeichenfolge einen Verweis auf diese Funktionen aus dem Hash haben. z.B

var customObject = {
  customFunction: function(param){...}
};

Dann können Sie anrufen:

customObject['customFunction'](param);

Wobei customFunction eine Zeichenfolge ist, die einer in Ihrem Objekt definierten Funktion entspricht.


@ibsenv, vielen Dank für Ihren Kommentar, der mir hilft, diese Antwort als die beste zu identifizieren. Ich habe ein Array von Funktionsobjekten erstellt und dieses wiederum verwendet, um ein Array von verzögerten Versprechungen zu erstellen. Ich habe unten einen Beispielcode eingefügt. (Ich wollte keine neue Antwort erstellen und Rubens Antwort ausleihen .)
user216661

Funktion getMyData (arrayOfObjectsWithIds) {var functionArray = arrayOfObjectsWithIds.map (Funktion (Wert) {return {myGetDataFunction: MyService.getMyData (value.id)};}) var versprechen = functionArray.map (Funktion (getDataFunction) {var deferred = q.defer (); getDataFunction.myGetDataFunction.success (Funktion (Daten) {deferred.resolve (Daten)}). error (Funktion (Fehler) {deferred.reject ();}); return deferred.promise;}); $ q.all (verspricht) .then (function (dataArray) {// mache Sachen})};
user216661

Dies funktioniert hervorragend. Ich füge nur Unterstrich / lodash hinzu, um zu überprüfen, ob es eine Funktion ist. Und dann laufen
elporfirio

35

Mit ES6 können Sie nach Namen auf Klassenmethoden zugreifen:

class X {
  method1(){
    console.log("1");
  }
  method2(){
    this['method1']();
    console.log("2");
  }
}
let x  = new X();
x['method2']();

die Ausgabe wäre:

1
2

1
Bestes Javascript PURE ... Gott .. Klasse löschen funktioniert nicht und aber es ist ok. Vielen Dank!
KingRider

1
Das ist das, wonach ich schon lange gesucht habe. Vielen Dank!
PaladiN

ES2015 hat hier nichts zu tun. Sie können dasselbe Ziel mit reinen Objekten oder Prototypdelegierung über erreichen Object.create(). const myObj = {method1 () {console.log ('1')}, method2 () {console.log ('2')}} myObj ['method1'] (); // 1 myObj ['method2'] (); // 2
Sminutoli

1
Das ist Gold !!! Ich bin überrascht, dass ich noch nie daran gedacht habe. Nett!!!
thxmike

Ich denke auch, dass dies der beste Weg ist, um unser Ziel zu erreichen.
Chris Jung

24

Zwei Dinge:

  • Vermeiden Sie Eval, es ist schrecklich gefährlich und langsam

  • zweitens spielt es keine Rolle, wo Ihre Funktion existiert, "globale" -ness ist irrelevant. x.y.foo()kann durch x.y['foo']()oder x['y']['foo']()oder sogar aktiviert werden window['x']['y']['foo'](). Sie können so unbegrenzt verketten.


1
Sie können jedoch nicht window ['xyz'] ()
ausführen

17

Bei allen Antworten wird davon ausgegangen, dass auf die Funktionen über den globalen Bereich (Fenster) zugegriffen werden kann. Das OP hat diese Annahme jedoch nicht getroffen.

Wenn die Funktionen in einem lokalen Bereich (auch als Closure bezeichnet) ausgeführt werden und nicht von einem anderen lokalen Objekt referenziert werden, Pech: Sie müssen eval()AFAIK verwenden, siehe Dynamisches Aufrufen der lokalen Funktion in Javascript


2
Alter (oder Typ), vielen Dank, dass Sie darauf hingewiesen haben! Ich dachte, ich würde für eine Sekunde verrückt.
Funktr0n

13

Sie müssen nur Ihre Zeichenfolge in einen Zeiger von konvertieren window[<method name>]. Beispiel:

var function_name = "string";
function_name = window[function_name];

und jetzt können Sie es wie einen Zeiger verwenden.


Dies scheint ein viel sichererer Weg zu sein.
James Poulose

12

Hier ist mein Beitrag zu den hervorragenden Antworten von Jason Bunting / Alex Nazarov, in denen ich die von Crashalot angeforderte Fehlerprüfung einbeziehe.

Angesichts dieser (erfundenen) Präambel:

a = function( args ) {
    console.log( 'global func passed:' );
    for( var i = 0; i < arguments.length; i++ ) {
        console.log( '-> ' + arguments[ i ] );
    }
};
ns = {};
ns.a = function( args ) {
    console.log( 'namespace func passed:' );
    for( var i = 0; i < arguments.length; i++ ) {
        console.log( '-> ' + arguments[ i ] ); 
    }
};
name = 'nsa';
n_s_a = [ 'Snowden' ];
noSuchAgency = function(){};

dann die folgende Funktion:

function executeFunctionByName( functionName, context /*, args */ ) {
    var args, namespaces, func;

    if( typeof functionName === 'undefined' ) { throw 'function name not specified'; }

    if( typeof eval( functionName ) !== 'function' ) { throw functionName + ' is not a function'; }

    if( typeof context !== 'undefined' ) { 
        if( typeof context === 'object' && context instanceof Array === false ) { 
            if( typeof context[ functionName ] !== 'function' ) {
                throw context + '.' + functionName + ' is not a function';
            }
            args = Array.prototype.slice.call( arguments, 2 );

        } else {
            args = Array.prototype.slice.call( arguments, 1 );
            context = window;
        }

    } else {
        context = window;
    }

    namespaces = functionName.split( "." );
    func = namespaces.pop();

    for( var i = 0; i < namespaces.length; i++ ) {
        context = context[ namespaces[ i ] ];
    }

    return context[ func ].apply( context, args );
}

Mit dieser Funktion können Sie eine Javascript-Funktion anhand eines Namens aufrufen, der in einer Zeichenfolge mit oder ohne Argument (einschließlich Array-Objekten) gespeichert ist, und Feedback zu aufgetretenen Fehlern geben (hoffentlich abfangen).

Die Beispielausgabe zeigt, wie es funktioniert:

// calling a global function without parms
executeFunctionByName( 'a' );
  /* OUTPUT:
  global func passed:
  */

// calling a global function passing a number (with implicit window context)
executeFunctionByName( 'a', 123 );
  /* OUTPUT:
  global func passed:
  -> 123
  */

// calling a namespaced function without parms
executeFunctionByName( 'ns.a' );
  /* OUTPUT:
  namespace func passed:
  */

// calling a namespaced function passing a string literal
executeFunctionByName( 'ns.a', 'No Such Agency!' );
  /* OUTPUT:
  namespace func passed:
  -> No Such Agency!
  */

// calling a namespaced function, with explicit context as separate arg, passing a string literal and array 
executeFunctionByName( 'a', ns, 'No Such Agency!', [ 007, 'is the man' ] );
  /* OUTPUT:
  namespace func passed:
  -> No Such Agency!
  -> 7,is the man
  */

// calling a global function passing a string variable (with implicit window context)
executeFunctionByName( 'a', name );
  /* OUTPUT:
  global func passed:
  -> nsa
  */

// calling a non-existing function via string literal
executeFunctionByName( 'n_s_a' );
  /* OUTPUT:
  Uncaught n_s_a is not a function
  */

// calling a non-existing function by string variable
executeFunctionByName( n_s_a );
  /* OUTPUT:
  Uncaught Snowden is not a function
  */

// calling an existing function with the wrong namespace reference
executeFunctionByName( 'a', {} );
  /* OUTPUT:
  Uncaught [object Object].a is not a function
  */

// calling no function
executeFunctionByName();
  /* OUTPUT:
  Uncaught function name not specified
  */

// calling by empty string
executeFunctionByName( '' );
  /* OUTPUT:
  Uncaught  is not a function
  */

// calling an existing global function with a namespace reference
executeFunctionByName( 'noSuchAgency', ns );
  /* OUTPUT:
  Uncaught [object Object].noSuchAgency is not a function
  */

Keine Ahnung ... es ist eine sehr gute Anstrengung, so klar. Aber klingt für mich "zu breit" ...
TechNyquist

2
Huh? SO ist eine Frage / Antwort / Lehrplattform. Ich werde gerne alle Beispiele zur Verfügung stellen, die mir einfallen, um hoffentlich die Beleuchtung zu vermitteln. Für mich ist das der Punkt .
Mac

Wenn Sie den Funktionsnamen trotzdem bewerten, warum nicht einfach diesen verwenden?
Daten

Das funktioniert bei mir nicht. Ich habe eine Namespace-Funktion abcd, wobei d der Funktionsname ist. Der Aufruf executeFunctionByName ("abcd", window) schlägt online fehl und prüft, ob der if( typeof context[ functionName ] !== 'function' )Kontext - window - definiert ist, ein Objekt und ein Array ist, aber das Fenster ['abcd'] existiert nicht, da es im akzeptierten als Problem identifiziert wurde Antwort: window["My.Namespace.functionName"](arguments); // fail
Akousmata

12

Je nachdem, wo Sie sich befinden, können Sie auch Folgendes verwenden:

this["funcname"]();
self["funcname"]();
window["funcname"]();
top["funcname"]();
globalThis["funcname"]();

oder in nodejs

global["funcname"]()

9

Wenn Sie eine Funktion eines Objekts anstelle einer globalen Funktion mit aufrufen möchten window["functionName"]. Du kannst es so machen;

var myObject=new Object();
myObject["functionName"](arguments);

Beispiel:

var now=new Date();
now["getFullYear"]()

8

ACHTUNG!!!

Man sollte aus zwei Gründen versuchen, das Aufrufen einer Funktion per String in JavaScript zu vermeiden:

Grund 1: Einige Code-Verschleierer zerstören Ihren Code, da sie die Funktionsnamen ändern und die Zeichenfolge ungültig machen.

Grund 2: Es ist viel schwieriger, Code zu verwalten, der diese Methode verwendet, da es viel schwieriger ist, die Verwendung der von einer Zeichenfolge aufgerufenen Methoden zu finden.


7

Hier ist mein Es6-Ansatz, mit dem Sie Ihre Funktion anhand ihres Namens als Zeichenfolge oder ihres Funktionsnamens aufrufen und verschiedene Arten von Argumenten an verschiedene Arten von Funktionen übergeben können:

function fnCall(fn, ...args)
{
  let func = (typeof fn =="string")?window[fn]:fn;
  if (typeof func == "function") func(...args);
  else throw new Error(`${fn} is Not a function!`);
}


function example1(arg1){console.log(arg1)}
function example2(arg1, arg2){console.log(arg1 + "  and   " + arg2)}
function example3(){console.log("No arguments!")}

fnCall("example1", "test_1");
fnCall("example2", "test_2", "test3");
fnCall(example3);
fnCall("example4"); // should raise an error in console


6

Überrascht, dass setTimeout nicht erwähnt wurde.

So führen Sie eine Funktion ohne Argumente aus:

var functionWithoutArguments = function(){
    console.log("Executing functionWithoutArguments");
}
setTimeout("functionWithoutArguments()", 0);

So führen Sie eine Funktion mit Argumenten aus:

var functionWithArguments = function(arg1, arg2) {
    console.log("Executing functionWithArguments", arg1, arg2);
}
setTimeout("functionWithArguments(10, 20)");

So führen Sie eine Funktion mit tiefem Namespace aus:

var _very = {
    _deeply: {
        _defined: {
            _function: function(num1, num2) {
                console.log("Execution _very _deeply _defined _function : ", num1, num2);
            }
        }
    }
}
setTimeout("_very._deeply._defined._function(40,50)", 0);

Dies gibt keine Antwort auf die Frage. Um einen Autor zu kritisieren oder um Klärung zu bitten, hinterlassen Sie einen Kommentar unter seinem Beitrag - Sie können jederzeit Ihre eigenen Beiträge kommentieren, und sobald Sie einen ausreichenden Ruf haben, können Sie dies tun jeden Beitrag kommentieren .
AstroCB

Bitte fügen Sie ein Beispiel hinzu, wie Sie runMemit ein paar Argumenten aufrufen würden .
Lexicore

1
@lexicore Ich habe für das Löschen in einer Überprüfungswarteschlange gestimmt , da es keine eindeutige Antwort auf die Frage liefert und für sich genommen von geringem Wert ist.
AstroCB

1
Diese Methode weist möglicherweise einen großen Fehler auf, da die Ausführung der Rendering- Warteschlange beendet wird und dieser Aufruf ausgeführt wird asynchron wird
PeterM

1
Ich mag diese Antwort, sie scheint für meine Anforderungen zu funktionieren.
Quintonn

3

Also, wie andere sagten, ist definitiv die beste Option:

window['myfunction'](arguments)

Und wie Jason Bunting sagte , funktioniert es nicht, wenn der Name Ihrer Funktion ein Objekt enthält:

window['myobject.myfunction'](arguments); // won't work
window['myobject']['myfunction'](arguments); // will work

Hier ist meine Version einer Funktion, die alle Funktionen nach Namen ausführt (einschließlich eines Objekts oder nicht):

my = {
    code : {
        is : {
            nice : function(a, b){ alert(a + "," + b); }
        }
    }
};

guy = function(){ alert('awesome'); }

function executeFunctionByName(str, args)
{
    var arr = str.split('.');
    var fn = window[ arr[0] ];
    
    for (var i = 1; i < arr.length; i++)
    { fn = fn[ arr[i] ]; }
    fn.apply(window, args);
}

executeFunctionByName('my.code.is.nice', ['arg1', 'arg2']);
executeFunctionByName('guy');


3
  let t0 = () => { alert('red0') }
  var t1 = () =>{ alert('red1') }
  var t2 = () =>{ alert('red2') }
  var t3 = () =>{ alert('red3') }
  var t4 = () =>{ alert('red4') }
  var t5 = () =>{ alert('red5') }
  var t6 = () =>{ alert('red6') }

  function getSelection(type) {
    var evalSelection = {
      'title0': t0,
      'title1': t1,
      'title2': t2,
      'title3': t3,
      'title4': t4,
      'title5': t5,
      'title6': t6,
      'default': function() {
        return 'Default';
      }
    };
    return (evalSelection[type] || evalSelection['default'])();
  }
  getSelection('title1');

Eine OOP-Lösung ...


2

Noch ein Detail zu den Posts von Jason und Alex. Ich fand es hilfreich, dem Kontext einen Standardwert hinzuzufügen. Einfach context = context == undefined? window:context;am Anfang der Funktion setzen. Sie können windowzu einem beliebigen bevorzugten Kontext wechseln und müssen dann nicht jedes Mal dieselbe Variable übergeben, wenn Sie dies in Ihrem Standardkontext aufrufen.


2

Um die Antwort von Jason Bunting zu ergänzen: Wenn Sie Nodejs oder ähnliches verwenden (und dies funktioniert auch in Dom Js), können Sie thisstattdessen window(und denken Sie daran: eval is evil :

this['fun'+'ctionName']();

2

In meinem Code ist etwas sehr Ähnliches. Ich habe eine vom Server generierte Zeichenfolge, die einen Funktionsnamen enthält, den ich als Rückruf für eine Bibliothek eines Drittanbieters übergeben muss. Ich habe also einen Code, der den String nimmt und einen "Zeiger" auf die Funktion zurückgibt, oder null, wenn er nicht gefunden wird.

Meine Lösung war der " sehr hilfreichen Funktion von Jason Bunting " * sehr ähnlich , obwohl sie nicht automatisch ausgeführt wird und der Kontext immer im Fenster angezeigt wird. Dies kann jedoch leicht geändert werden.

Hoffentlich ist dies für jemanden hilfreich.

/**
 * Converts a string containing a function or object method name to a function pointer.
 * @param  string   func
 * @return function
 */
function getFuncFromString(func) {
    // if already a function, return
    if (typeof func === 'function') return func;

    // if string, try to find function or method of object (of "obj.func" format)
    if (typeof func === 'string') {
        if (!func.length) return null;
        var target = window;
        var func = func.split('.');
        while (func.length) {
            var ns = func.shift();
            if (typeof target[ns] === 'undefined') return null;
            target = target[ns];
        }
        if (typeof target === 'function') return target;
    }

    // return null if could not parse
    return null;
}


1

Ich kann nicht widerstehen, einen anderen Trick zu erwähnen, der hilft, wenn Sie eine unbekannte Anzahl von Argumenten haben, die auch als Teil der Zeichenfolge übergeben werden, die den Funktionsnamen enthält. Zum Beispiel:

var annoyingstring = 'call_my_func(123, true, "blah")';

Wenn Ihr Javascript auf einer HTML-Seite ausgeführt wird, benötigen Sie lediglich einen unsichtbaren Link. Sie können eine Zeichenfolge an das onclickAttribut übergeben und die clickMethode aufrufen .

<a href="#" id="link_secret"><!-- invisible --></a>

$('#link_secret').attr('onclick', annoyingstring);
$('#link_secret').click();

Oder erstellen Sie das <a>Element zur Laufzeit.


Kreative Lösung, dies funktioniert jedoch nicht für Argumente vom Typ Objekt oder Array.
Dennis Heiden

1
Dies verwendet eval unter der Haube ... Und wirklich um den heißen
Juan Mendes

1

Am einfachsten ist es, darauf zuzugreifen, als hätte es ein Element

window.ClientSideValidations.forms.location_form

ist das gleiche wie

window.ClientSideValidations.forms['location_form']

1

Sie können die Javascript-Funktion in eval("functionname as string")beiden aufrufen . Wie unten: (eval ist reine Javascript-Funktion)

function testfunc(){
    return "hello world";
}

$( document ).ready(function() {

     $("div").html(eval("testfunc"));
});

Arbeitsbeispiel: https://jsfiddle.net/suatatan/24ms0fna/4/


Dies funktioniert gut und es ist so einfach
Carlos E

1
Und auch sehr langsam.
Marco

1

Das funktioniert bei mir:

var command = "Add";
var tempFunction = new Function("Arg1","Arg2", "window." + command + "(Arg1,Arg2)");
tempFunction(x,y);

Ich hoffe das funktioniert.


1

Ich glaube nicht, dass Sie komplizierte Zwischenfunktionen oder Auswertungen benötigen oder von globalen Variablen wie window abhängig sind:

function fun1(arg) {
  console.log(arg);
}

function fun2(arg) {
  console.log(arg);
}

const operations = {
  fun1,
  fun2
};

let temp = "fun1";

try {
  // You have to use square brackets property access
  operations["fun1"]("Hello World");
  operations["fun2"]("Hello World");
  // You can use variables
  operations[temp]("Hello World");
} catch (error) {
  console.error(error);
}

Es funktioniert auch mit importierten Funktionen:

// mode.js
export function fun1(arg) {
  console.log(arg);
}

export function fun2(arg) {
  console.log(arg);
}
// index.js
import { fun1, fun2 } from "./mod";

const operations = {
  fun1,
  fun2
};

try {
  operations["fun1"]("Hello World");
  operations["fun2"]("Hello World");
} catch (error) {
  console.error(error);
}

0

Ohne Verwendung können eval('function()')Sie mit eine neue Funktion erstellen new Function(strName). Der folgende Code wurde mit FF, Chrome, IE getestet.

<html>
<body>
<button onclick="test()">Try it</button>
</body>
</html>
<script type="text/javascript">

  function test() {
    try {    
        var fnName = "myFunction()";
        var fn = new Function(fnName);
        fn();
      } catch (err) {
        console.log("error:"+err.message);
      }
  }

  function myFunction() {
    console.log('Executing myFunction()');
  }

</script>

0
use this

function executeFunctionByName(functionName, context /*, args */) {
      var args = [].slice.call(arguments).splice(2);
      var namespaces = functionName.split(".");
      var func = namespaces.pop();
      for(var i = 0; i < namespaces.length; i++) {
        context = context[namespaces[i]];
      }
      return context[func].apply(context, args);
    }

1
Warum? Antworten ohne Erklärung sind höchstwahrscheinlich nutzlos.
Daniel W.

0

Einfach aussehen:

var namefunction = 'jspure'; // String

function jspure(msg1 = '', msg2 = '') { 
  console.log(msg1+(msg2!=''?'/'+msg2:''));
} // multiple argument

// Results ur test
window[namefunction]('hello','hello again'); // something...
eval[namefunction] = 'hello'; // use string or something, but its eval just one argument and not exist multiple

Bestehende andere Typfunktion ist Klasse und Aussehen Beispiel nils petersohn


0

Danke für die sehr hilfreiche Antwort. Ich benutze die Funktion von Jason Bunting in meinen Projekten.

Ich habe es erweitert, um es mit einem optionalen Zeitlimit zu verwenden, da die normale Methode zum Festlegen eines Zeitlimits nicht funktioniert. Siehe abhishekisnots Frage

function executeFunctionByName(functionName, context, timeout /*, args */ ) {
	var args = Array.prototype.slice.call(arguments, 3);
	var namespaces = functionName.split(".");
	var func = namespaces.pop();
	for (var i = 0; i < namespaces.length; i++) {
		context = context[namespaces[i]];
	}
	var timeoutID = setTimeout(
		function(){ context[func].apply(context, args)},
		timeout
	);
    return timeoutID;
}

var _very = {
    _deeply: {
        _defined: {
            _function: function(num1, num2) {
                console.log("Execution _very _deeply _defined _function : ", num1, num2);
            }
        }
    }
}

console.log('now wait')
executeFunctionByName("_very._deeply._defined._function", window, 2000, 40, 50 );

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.