Comment transformer une chaîne en appel de fonction JavaScript? [dupliquer]

cette question a déjà une réponse ici:

j'ai eu une chaîne de caractères comme:

settings.functionName + '(' + t.parentNode.id + ')';

que je veux traduire en un appel de fonction comme ceci:

clickedOnItem(IdofParent);

cela devra bien sûr être fait en JavaScript. Quand je fais une alerte sur settings.functionName + '(' + t.parentNode.id + ')'; il semble pour tout corriger. J'ai juste besoin d'appeler la fonction dans laquelle ça se traduirait.

légende:

settings.functionName = clickedOnItem

t.parentNode.id = IdofParent
240
demandé sur Brett DeWoody 2009-05-27 00:31:03
la source

13 ответов

vu que je déteste eval, et je suis pas seul :

var fn = window[settings.functionName];
if(typeof fn === 'function') {
    fn(t.parentNode.id);
}

Edit: en réponse au commentaire de @Mahan: Dans ce cas particulier, settings.functionName serait "clickedOnItem" . À l'exécution, cela traduirait var fn = window[settings.functionName]; en var fn = window["clickedOnItem"] , ce qui donnerait une référence à function clickedOnItem (nodeId) {} . Une fois que nous avons une référence à une fonction à l'intérieur d'une variable, nous pouvons appeler cette fonction en "appelant la variable", c'est-à-dire fn(t.parentNode.id) , ce qui équivaut à clickedOnItem(t.parentNode.id) , ce que voulait L'OP.

exemple plus complet:

/* Somewhere: */
window.settings = {
  /* [..] Other settings */
  functionName: 'clickedOnItem'
  /* , [..] More settings */
};

/* Later */
function clickedOnItem (nodeId) {
  /* Some cool event handling code here */
}

/* Even later */
var fn = window[settings.functionName]; 
/* note that settings.functionName could also be written
   as window.settings.functionName. In this case, we use the fact that window
   is the implied scope of global variables. */
if(typeof fn === 'function') {
    fn(t.parentNode.id);
}
334
répondu PatrikAkerstrand 2012-05-24 11:39:58
la source
window[settings.functionName](t.parentNode.id);

pas besoin d'évaluation ()

67
répondu Fabien Ménager 2009-05-27 00:37:50
la source

Voici une façon plus générique de faire la même chose, tout en supportant les portées:

// Get function from string, with or without scopes (by Nicolas Gauthier)
window.getFunctionFromString = function(string)
{
    var scope = window;
    var scopeSplit = string.split('.');
    for (i = 0; i < scopeSplit.length - 1; i++)
    {
        scope = scope[scopeSplit[i]];

        if (scope == undefined) return;
    }

    return scope[scopeSplit[scopeSplit.length - 1]];
}

J'espère que ça peut aider certaines personnes.

64
répondu NGauthier 2013-12-28 18:22:13
la source

JavaScript a une fonction eval qui évalue une chaîne de caractères et l'exécute comme code:

eval(settings.functionName + '(' + t.parentNode.id + ')');
15
répondu Andrew Hare 2009-05-27 00:33:10
la source

eval () est la fonction dont vous avez besoin pour faire cela, mais je conseillerais d'essayer une de ces choses pour minimiser l'utilisation d'eval. Avec un peu de chance, l'un d'eux vous semblera logique.

stocker la fonction

stocke la fonction comme une fonction, pas comme une chaîne, et l'utilise comme une fonction plus tard. L'emplacement où vous stockez la fonction est à vous.

var funcForLater = clickedOnItem;

// later is now
funcForLater(t.parentNode.id);

ou

someObject.funcForLater = clickedOnItem;    
// later is now    
(someObject.funcForLater)(t.parentNode.id);

Stocker le nom de la fonction

même si vous devez stocker le nom de la fonction comme une chaîne, vous pouvez minimiser la complexité en faisant

(eval(settings.functionName))(t.parentNode.id);

qui minimise la quantité de Javascript que vous devez construire et évaluer.

Dictionnaire des gestionnaires

mettez toutes les fonctions d'action dont vous pourriez avoir besoin dans un objet, et appelez-les dictionnaire-style en utilisant la chaîne.

// global
itemActions = { click: clickedOnItem, rightClick: rightClickedOnItem /* etc */ };

// Later...
var actionName = "click"; // Or wherever you got the action name
var actionToDo = itemActions[actionName];
actionToDo(t.parentNode.id);

(Note mineure: si à la place vous utilisiez la syntaxe itemActions[actionName](t.parentNode.id); , alors la fonction serait appelée comme une méthode de itemActions .)

12
répondu Jesse Millikan 2015-02-22 05:34:52
la source

bien que j'aime la première réponse et que je déteste eval, j'aimerais ajouter qu'il y a une autre façon (semblable à eval) donc si vous pouvez contourner et ne pas l'utiliser, vous feriez mieux de le faire. Mais dans certains cas, vous pouvez appeler du code javascript avant ou après un appel ajax et si vous avez ce code dans un attribut personnalisé au lieu d'ajax, vous pouvez utiliser ceci:

    var executeBefore = $(el).attr("data-execute-before-ajax");
    if (executeBefore != "") {
        var fn = new Function(executeBefore);
        fn();
    }

ou éventuellement le stocker dans un cache de fonction si vous pouvez avoir besoin de l'appeler plusieurs fois.

encore une fois-n'utilisez pas eval ou cette méthode si vous avez une autre façon de le faire.

9
répondu nsimeonov 2015-02-17 20:21:20
la source

si settings.functionName est déjà une fonction, vous pouvez le faire:

settings.functionName(t.parentNode.id);

, Sinon, cela devrait aussi fonctionner si settings.functionName est juste le nom de la fonction:

if (typeof window[settings.functionName] == "function") {
    window[settings.functionName](t.parentNode.id);
}
7
répondu Gumbo 2009-05-27 00:34:54
la source

je voulais pouvoir prendre un nom de fonction comme chaîne, l'appeler, et passer un argument à la fonction. Je ne pouvais pas obtenir la réponse choisie pour cette question pour le faire, mais ce réponse expliqué exactement, et voici une courte démo.

function test_function(argument)    {
    alert('This function ' + argument); 
}

functionName = 'test_function';

window[functionName]('works!');

Cela fonctionne aussi avec plusieurs arguments.

7
répondu B Rad C 2017-05-23 15:18:17
la source

cela m'a pris un certain temps à comprendre, car le conventionnel window['someFunctionName']() ne fonctionnait pas pour moi au début. Les noms de mes fonctions étaient tirés comme une réponse AJAX d'une base de données. En outre, pour quelque raison que ce soit, mes fonctions ont été déclarées en dehors de la portée de la fenêtre, donc pour corriger ceci j'ai dû réécrire les fonctions que j'appelais de

function someFunctionName() {}

à

window.someFunctionName = function() {}

et de là je pouvais appeler window['someFunctionName']() avec facilité. J'espère que cela aide quelqu'un!

3
répondu illusivefingers 2012-02-26 04:16:07
la source

D'après la réponse de Nicolas Gauthier:

var strng = 'someobj.someCallback';
var data = 'someData';

var func = window;
var funcSplit = strng.split('.');
for(i = 0;i < funcSplit.length;i++){
   //We maybe can check typeof and break the bucle if typeof != function
   func = func[funcSplit[i]];
}
func(data);
2
répondu Marcos Fernandez Ramos 2013-04-10 00:13:35
la source

je préfère utiliser quelque chose comme ceci:

window.callbackClass['newFunctionName'] = function(data) { console.log(data) };
...
window.callbackClass['newFunctionName'](data);
1
répondu Tom Johnson 2012-03-05 19:29:07
la source

en javascript qui utilise la spécification CommonJS, comme noeud.js par exemple, vous pouvez faire ce que je montre ci-dessous. Ce qui est assez pratique pour accéder à une variable par une chaîne même si elle n'est pas définie sur l'objet window . S'il y a une classe appelée MyClass , définie dans un module CommonJS appelé MyClass.js

// MyClass.js
var MyClass = function() {
    // I do stuff in here. Probably return an object
    return {
       foo: "bar"
    }
}

module.exports = MyClass;

vous pouvez alors faire ce joli morceau o sorcellerie d'un autre dossier appelé MyOtherFile.js

// MyOtherFile.js

var myString = "MyClass";

var MyClass = require('./' + myString);
var obj = new MyClass();

console.log(obj.foo); // returns "bar"

une raison de plus pourquoi CommonJS est un tel plaisir.

0
répondu nackjicholson 2016-02-29 21:04:30
la source
eval("javascript code");

il est largement utilisé en traitant avec JSON .

-6
répondu 2009-05-27 00:34:07
la source

Autres questions sur javascript function