Ces deux fonctions font-elles la même chose dans les coulisses? (dans les fonctions d'instruction unique)
var evaluate = function(string) {
return eval('(' + string + ')');
}
var func = function(string) {
return (new Function( 'return (' + string + ')' )());
}
console.log(evaluate('2 + 1'));
console.log(func('2 + 1'));
javascript
function
optimization
eval
qwertymk
la source
la source
new
considéré dans cette discussion?Function
instancie implicitement unfunction object
. L'exclusionnew
ne changera pas du tout le code. Voici un jsfiddle démontrant que: jsfiddle.net/PcfG8Réponses:
Non, ce ne sont pas les mêmes.
eval()
évalue une chaîne en tant qu'expression JavaScript dans la portée d'exécution actuelle et peut accéder aux variables locales.new Function()
analyse le code JavaScript stocké dans une chaîne dans un objet fonction, qui peut ensuite être appelé. Il ne peut pas accéder aux variables locales car le code s'exécute dans une portée distincte.Considérez ce code:
Si elles
new Function('return (a = 22);')()
étaient utilisées, la variable localea
conserverait sa valeur. Néanmoins, certains programmeurs JavaScript tels que Douglas Crockford pensent que ni l'un ni l'autre ne devrait être utilisé à moins que cela ne soit absolument nécessaire , et l'évaluation / l'utilisation duFunction
constructeur sur des données non fiables n'est pas sécurisée et imprudente.la source
new Function(code)
c'est la même choseeval('(function(){'+code+'})()')
ou s'agit-il d'un contexte d'exécution entièrement nouveau?eval('(function(){'+code+'})')
, ce qui renverrait un objet fonction. Selon MDN , «les fonctions créées avec le constructeur Function ne créent pas de fermetures dans leurs contextes de création; elles s'exécutent toujours dans le contexte de la fenêtre (sauf si le corps de la fonction commence par une instruction" use strict ";, auquel cas le contexte n'est pas défini) . "Non.
Dans votre mise à jour, les appels à
evaluate
etfunc
produisent le même résultat. Mais ils ne "font certainement pas la même chose dans les coulisses". Lafunc
fonction crée une nouvelle fonction, mais l'exécute immédiatement, alors que laevaluate
fonction exécute simplement le code sur place.De la question d'origine:
Ceux-ci vous donneront des résultats très différents:
la source
return eval('(' + string + ')');
alors ils donneraient les mêmes résultats.new Function
crée une fonction qui peut être réutilisée.eval
exécute simplement la chaîne donnée et renvoie le résultat de la dernière instruction. Votre question est erronée lorsque vous avez tenté de créer une fonction wrapper qui utilise Function pour émuler une évaluation.Est-il vrai qu'ils partagent du code derrière les rideaux? Oui, très probablement. Exactement le même code? Non, certainement.
Pour le plaisir, voici ma propre implémentation imparfaite utilisant eval pour créer une fonction. J'espère que cela éclairera la différence!
La plus grande différence entre cette fonction et la nouvelle fonction est que la fonction n'est pas de portée lexicale. Il n'aurait donc pas accès aux variables de fermeture et la mienne le ferait.
la source
arguments.slice()
place de la boucle for? Ou si les arguments n'est pas un tableau vrai,[].slice.call(arguments, 1)
.Je veux juste souligner une syntaxe utilisée dans les exemples ici et ce que cela signifie:
notez que la fonction (...) () a le "()" à la fin. Cette syntaxe obligera func à exécuter la nouvelle fonction et à renvoyer la chaîne, pas une fonction qui renvoie une chaîne, mais si vous utilisez ce qui suit:
Maintenant func retournera une fonction qui retourne une chaîne.
la source
Si vous voulez dire, cela donnera-t-il les mêmes résultats, alors oui ... mais juste pour eval (aka, "évaluer cette chaîne de JavaScript") serait beaucoup plus simple.
EDIT ci-dessous:
C'est comme dire ... ces deux problèmes mathématiques sont-ils les mêmes:
1 + 1
1 + 1 + 1 - 1 + 1 - 1 * 1/1
la source
Function
objet stocke probablement la chaîne dans une variable de membre privéeval
lorsque vous appelez la fonction.Dans cet exemple, les résultats sont les mêmes, oui. Les deux exécutent l'expression que vous transmettez. C'est ce qui les rend si dangereux.
Mais ils font des choses différentes derrière le scense. Celui qui implique
new Function()
, en coulisses, crée une fonction anonyme à partir du code que vous fournissez, qui est exécutée lorsque la fonction est appelée.Le JavaScript que vous lui transmettez n'est techniquement pas exécuté tant que vous n'appelez pas la fonction anonyme. Cela contraste avec
eval()
qui exécute le code tout de suite et ne génère pas de fonction basée sur celui-ci.la source
Does the Function() one use another stack call level than eval?
: Je suppose que oui, careval()
ne crée pas de fonction à partir de votre entrée - il l'exécute simplement.new Function()
crée une nouvelle fonction, qu'il appelle ensuite.