N'utilisez pas eval
sauf si vous n'avez absolument aucun autre choix.
Comme cela a été mentionné, l'utilisation de quelque chose comme ça serait la meilleure façon de le faire:
window["functionName"](arguments);
Cela, cependant, ne fonctionnera pas avec une fonction namespace'd:
window["My.Namespace.functionName"](arguments); // fail
Voici comment procéder:
window["My"]["Namespace"]["functionName"](arguments); // succeeds
Afin de faciliter cela et d'offrir une certaine flexibilité, voici une fonction pratique:
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);
}
Vous l'appeleriez ainsi:
executeFunctionByName("My.Namespace.functionName", window, arguments);
Remarque, vous pouvez passer dans le contexte que vous voulez, donc cela ferait la même chose que ci-dessus:
executeFunctionByName("Namespace.functionName", My, arguments);
My.Namespace.functionName()
,this
fera référence à l'My.Namespace
objet. Mais lorsque vous appelezexecuteFunctionByName("My.Namespace.functionName", window)
, il n'y a aucun moyen de fairethis
référence à la même chose. Il devrait peut-être utiliser le dernier espace de noms comme étendue, ouwindow
s'il n'y a pas d'espaces de noms. Ou vous pouvez autoriser l'utilisateur à spécifier la portée comme argument.Je pensais juste publier une version légèrement modifiée de la fonction très utile de Jason Bunting .
Tout d'abord, j'ai simplifié la première instruction en fournissant un deuxième paramètre à slice () . La version originale fonctionnait bien dans tous les navigateurs sauf IE.
Deuxièmement, j'ai remplacé cela par le contexte dans la déclaration de retour; sinon, cela pointait toujours vers la fenêtre lors de l'exécution de la fonction cible.
la source
La réponse à cette autre question vous montre comment faire: l' équivalent Javascript des locals de Python ()?
En gros, vous pouvez dire
ou comme beaucoup d'autres l'ont suggéré, vous pouvez simplement utiliser eval:
bien que cela soit extrêmement dangereux, sauf si vous êtes absolument sûr de ce que vous évaluez.
la source
Ne pourriez-vous pas simplement faire ceci:
Vous pouvez également exécuter tout autre JavaScript à l'aide de cette méthode.
la source
eval("My.Namespace.functionName()");
?var codeToExecute = "return My.Namespace.functionName()";
Je pense qu'une façon élégante de le faire est de définir vos fonctions dans un objet de hachage. Ensuite, vous pouvez avoir une référence à ces fonctions à partir du hachage en utilisant la chaîne. par exemple
Ensuite, vous pouvez appeler:
Où customFunction sera une chaîne correspondant à une fonction définie dans votre objet.
la source
Avec ES6, vous pouvez accéder aux méthodes de classe par nom:
la sortie serait:
la source
Object.create()
. const myObj = {method1 () {console.log ('1')}, method2 () {console.log ('2')}} myObj ['method1'] (); // 1 myObj ['méthode2'] (); // 2Deux choses:
éviter l'eval, c'est terriblement dangereux et lent
deuxièmement, peu importe où se trouve votre fonction, la "globalité" n'est pas pertinente.
x.y.foo()
peut être activé viax.y['foo']()
oux['y']['foo']()
ou mêmewindow['x']['y']['foo']()
. Vous pouvez enchaîner indéfiniment comme ça.la source
Toutes les réponses supposent que les fonctions sont accessibles via une portée globale (fenêtre). Cependant, le PO n'a pas fait cette hypothèse.
Si les fonctions vivent dans une portée locale (aka fermeture) et ne sont pas référencées par un autre objet local, pas de chance: vous devez utiliser
eval()
AFAIK, voir appeler dynamiquement la fonction locale en javascriptla source
Vous avez juste besoin de convertir votre chaîne en pointeur par
window[<method name>]
. exemple:et maintenant vous pouvez l'utiliser comme un pointeur.
la source
Voici ma contribution aux excellentes réponses de Jason Bunting / Alex Nazarov, où j'inclus la vérification des erreurs demandée par Crashalot.
Compte tenu de ce préambule (artificiel):
puis la fonction suivante:
vous permettra d'appeler une fonction javascript par nom stocké dans une chaîne, à espace de noms ou globale, avec ou sans arguments (y compris les objets Array), fournissant des commentaires sur toutes les erreurs rencontrées (en espérant les attraper).
L'exemple de sortie montre comment cela fonctionne:
la source
if( typeof context[ functionName ] !== 'function' )
parce que le contexte - fenêtre - est défini, est un objet et un tableau, mais la fenêtre ['abcd'] n'existe pas car elle a été identifiée comme un problème dans l'accepté réponse:window["My.Namespace.functionName"](arguments); // fail
Selon l'endroit où vous vous trouvez, vous pouvez également utiliser:
ou, dans nodejs
la source
Si vous souhaitez appeler une fonction d'un objet au lieu d'une fonction globale avec
window["functionName"]
. Vous pouvez le faire comme;Exemple:
la source
FAITES ATTENTION!!!
Il faut essayer d'éviter d'appeler une fonction par chaîne en JavaScript pour deux raisons:
Raison 1: certains obfuscateurs de code vont détruire votre code car ils changeront les noms de fonction, rendant la chaîne invalide.
Raison 2: Il est beaucoup plus difficile de maintenir le code qui utilise cette méthodologie car il est beaucoup plus difficile de localiser les utilisations des méthodes appelées par une chaîne.
la source
Voici mon approche Es6 qui vous permet d'appeler votre fonction par son nom en tant que chaîne ou son nom de fonction et vous permet également de passer différents nombres d'arguments à différents types de fonctions:
la source
Surpris de ne voir aucune mention de setTimeout.
Pour exécuter une fonction sans arguments:
Pour exécuter la fonction avec des arguments:
Pour exécuter une fonction à espace de noms profond:
la source
runMe
avec quelques arguments.Ainsi, comme d'autres l'ont dit, la meilleure option est certainement:
Et comme Jason Bunting l'a dit , cela ne fonctionnera pas si le nom de votre fonction inclut un objet:
Voici donc ma version d'une fonction qui exécutera toutes les fonctions par leur nom (y compris un objet ou non):
la source
Une solution plus POO ...
la source
Un détail supplémentaire sur les publications de Jason et Alex. J'ai trouvé utile d'ajouter une valeur par défaut au contexte. Mettez juste
context = context == undefined? window:context;
au début de la fonction. Vous pouvez changerwindow
quel que soit votre contexte préféré, puis vous n'aurez pas besoin de passer la même variable chaque fois que vous l'appelez dans votre contexte par défaut.la source
Pour ajouter à la réponse de Jason Bunting, si vous utilisez nodejs ou quelque chose (et cela fonctionne aussi dans dom js), vous pouvez utiliser à la
this
place dewindow
(et rappelez-vous: eval is evil :la source
Il y a une chose très similaire dans mon code. J'ai une chaîne générée par le serveur qui contient un nom de fonction que je dois passer comme rappel pour une bibliothèque tierce. J'ai donc un code qui prend la chaîne et retourne un "pointeur" sur la fonction, ou null s'il n'est pas trouvé.
Ma solution était très similaire à " la fonction très utile de Jason Bunting " * , bien qu'elle ne s'exécute pas automatiquement et que le contexte soit toujours sur la fenêtre. Mais cela peut être facilement modifié.
J'espère que cela sera utile à quelqu'un.
la source
Là aussi, un moyen très utile.
http://devlicio.us/blogs/sergio_pereira/archive/2009/02/09/javascript-5-ways-to-call-a-function.aspx
la source
Je ne peux pas résister à mentionner une autre astuce, ce qui aide si vous avez un nombre inconnu d'arguments qui sont également passés dans le cadre de la chaîne contenant le nom de la fonction. Par exemple:
var annoyingstring = 'call_my_func(123, true, "blah")';
Si votre Javascript fonctionne sur une page HTML, tout ce dont vous avez besoin est un lien invisible; vous pouvez passer une chaîne dans l'
onclick
attribut et appeler laclick
méthode.<a href="#" id="link_secret"><!-- invisible --></a>
Ou créez l'
<a>
élément au moment de l'exécution.la source
Le moyen le plus simple est d'y accéder comme un élément
est identique à
la source
Vous pouvez appeler la fonction javascript dans l'un
eval("functionname as string")
ou l' autre. Comme ci-dessous: (eval est une fonction javascript pure)Exemple de travail: https://jsfiddle.net/suatatan/24ms0fna/4/
la source
Cela fonctionne pour moi:
J'espère que cela fonctionne.
la source
Je ne pense pas que vous ayez besoin de fonctions intermédiaires ou d'évaluation complexes ou que vous dépendiez de variables globales comme la fenêtre:
Il fonctionnera également avec les fonctions importées:
la source
Sans utiliser,
eval('function()')
vous pourriez créer une nouvelle fonction en utilisantnew Function(strName)
. Le code ci-dessous a été testé à l'aide de FF, Chrome, IE.la source
la source
Regardez basique:
Existe une autre fonction de type est la classe et regarde l'exemple nils petersohn
la source
Merci pour la réponse très utile. J'utilise la fonction de Jason Bunting dans mes projets.
Je l'ai étendu pour l'utiliser avec un délai d'attente facultatif, car la façon normale de définir un délai d'attente ne fonctionnera pas. Voir la question de abhishekisnot
la source