2
votes

Que fait l'expression eval (function () {} ()) en javascript?

J'ai trouvé ce script sur une page Web:

eval(function(a, b, c, d, e, f) {
    //do some thing here and return value
}(val1, val2, val3, val4, val5, {}))

Savez-vous ce que fait vraiment l'expression ci-dessus?


7 commentaires

Avez-vous recherché eval () sur le net? w3schools.com/jsref/jsref_eval.asp


function (param) {console.log (param)} ("hello world") affichera immédiatement "hello world" . C'est une expression de fonction IIFE - exécutée immédiatement qui a des paramètres fournis dans la dernière parenthèse.


J'appellerai la fonction avec a = val1, b = val2 ....


Je pense que la question ne concerne pas uniquement eval mais l'ensemble de la construction. Je suis d'accord que l'IIFE à l'intérieur rend l'utilisation dans son ensemble beaucoup plus difficile à comprendre en un coup d'œil, mais si vous savez ce que font les IIFE, c'est plus clair. Eh bien, dans une certaine mesure - l'expression interne générera probablement du code, mais nous ne savons pas quoi - eval le consomme ensuite.


JAMAIS, JAMAIS, JAMAIS, MAIS NE JAMAIS utiliser eval JAMAIS!


@Mouser ne dites jamais jamais . Bien que je convienne que dans la plupart des cas d'utilisation raisonnables, la nouvelle fonction est meilleure que eval .


Veuillez poster le code complet de faire quelque chose ici et renvoyer la valeur


3 Réponses :


0
votes

La méthode

eval est en fait utilisée pour exécuter des scripts dès que l'instruction eval est exécutée. Il peut exécuter un script au format string . Tout comme ci-dessous -

eval("console.log('hello world')")

Dans votre cas, il ne s'agit en fait que d'exécuter le script dès que cette instruction est exécutée.


2 commentaires

Sauf que cela fait plus que "exécuter le script". Il le GENERE avant que eval ne soit appelé.


Aussi, pour l'enregistrement eval (console.log ('hello world')) ne fait la même chose que la première ligne par coïncidence. Il évalue en fait console.log ('bonjour le monde') d'abord , qui s'imprime sur la console, puis il appelle eval (undefined) car console.log () ne renvoie rien. Donc, c'est équivalent à console.log ('hello world') suivi d'une ligne qui est simplement eval () et donc sans entrée, c'est un no-op et ignoré. Ce n'est pas en fait un équivalent.



1
votes

Cela fait 2 choses.

  1. Crée une fonction anonyme et l'exécute.
  2. eval les résultats de la fonction.

Voici un exemple simplifié.

eval(
  function(a) {
    let str = a + ' world'
    let toEval = 'console.log("' + str + '")'
    // the string is now -> 'console.log("hello world")'
    return toEval
  }('hello')
)

Définit une fonction qui accepte une chaîne, ajoute 'world' et crée du code sous forme de nouvelle chaîne, puis la renvoie. Cette fonction n'a pas de nom , tout comme anonymous.

Exécute la fonction avec le paramètre hello .

Ensuite, exécutez le code retourné (sous forme de chaîne) en utilisant eval.


0 commentaires

2
votes

Décompressons les choses un par un, d'abord la partie interne

eval(function(limit, toPrint) {
    return "for (var i = 0; i < " + limit + "; i++) { console.log('" + toPrint + "') }"
}(3, "foo"))

En fait, simplifions encore plus

eval("console.log('this comes from eval()')");


var evalCanReturnResults = eval("1 + 2");
console.log(evalCanReturnResults);


var a = 3;
var b = 4;
var evalCanUseVariables = eval("a + b");

console.log(evalCanUseVariables);

Ceci est appelé une expression de fonction immédiatement appelée a > ou très souvent abrégé en IIFE. C'est plutôt ennuyeux, honnêtement, le nom est la description complète mais permettez-moi de reformuler - c'est une fonction qui est déclarée puis exécutée immédiatement. Ceci est fait par les derniers crochets () - exactement comment vous exécuteriez autrement une fonction, par exemple parseInt () . Dans ce cas simple, il imprime simplement quelque chose sur la console et se termine.

Cependant, c'est une fonction normale et elle peut faire tout ce que vous voulez, y compris les paramètres de prise:

var someVariable = "hello";
var anotherVariable = "world";

var resultFromIIFE = (function(param1, param2) { //takes two parameters
    console.log("this was executed with parameters", param1, param2);
    return param1 + param2;
}(someVariable, anotherVariable));

console.log(resultFromIIFE);

Donc, vous pouvez faire beaucoup plus de choses. Vous pouvez même renvoyer une valeur et les paramètres passés à la fonction peuvent être des variables:

(function(param1, param2) { //takes two parameters
    console.log("this was executed with parameters", param1, param2);
}("hello", "world"))//these are passed to the function

Donc, j'espère que cela clarifie la partie intérieure. J'y reviendrai.

Quant à eval - il prend une chaîne et l'exécute comme code JavaScript .

(function() { //takes no paremeters
    console.log("this was executed");
}())//no parameters given here

C'est un cours intensif rapide sur eval . Il suffit de comprendre qu'il peut prendre n'importe quelle chaîne arbitraire et l'exécuter en JS.

Donc, si nous mettons les deux ensemble, l'IIFE interne générera probablement du code dynamiquement pour que eval s'exécute. Par exemple, vous pourriez avoir quelque chose comme ::

function(a, b, c, d, e, f) {
    //do some thing here and return value
}(val1, val2, val3, val4, val5, {})

Ce qui va générer une boucle for avec les paramètres spécifiés et l'exécuter.


3 commentaires

Aucun problème. Pourriez-vous parler de la nature de POURQUOI quelqu'un choisirait cette voie? Y a-t-il un avantage à utiliser un IIFE pour générer une fonction et l'exécuter avec eval? Eval est généralement considérée comme une pratique dangereuse et mauvaise, alors existe-t-il une alternative qui n'utilise pas eval qui permettrait d'obtenir le même résultat sans eval?


@Nate Je ne peux vraiment pas dire pourquoi cela a été choisi. Pas sans voir le code. Même sans cela, il serait étrange d'avoir du code qui génère un autre code que vous exécutez - sûrement, si vous pouvez générer le code, vous pouvez également ignorer eval et faire en sorte que votre code produise le résultat nécessaire. Vous avez raison de dire que eval est considéré comme dangereux, donc je soupçonne que cela pourrait être l'utilisation - je peux voir qu'il est utilisé comme une méthode d'obfuscation de code malveillant. Cela pourrait aussi être un piratage utilisé par quelqu'un - eval est souvent utilisé comme béquille. Il peut y avoir des utilisations comme la programmation dynamique mais je n'en connais pas assez pour dire


Merci pour la perspicacité!