2010-10-20 26 views
4

Utiliser JSlint pour valider mon javascript.eval est un problème mal

Je reçois une erreur disant que eval est diabolique! Pourquoi est-ce et existe-t-il une alternative que je peux utiliser?

Voici un exemple d'où j'utilise eval et je voudrais une solution de contournement pour cela.

J'ai un tableau comme celui-ci:

var Resources = { 
message_1: 'Message 1', 
message_2: 'Message 2', 
message_3: 'Message 3', 
message_4: 'Message 4' 
}; 

J'ai une fonction (functionResult) qui retourne un chiffre, soit 1, 2, 3 ou 4. Donc ce que je veux faire dans la ligne suivante de code est obtenir la ressource dans le tableau que le message se termine dans le résultat de ma fonction.

$('#divPresenter').html(eval($.validator.format('Resources.message_{0}', functionResult))); 

Des idées comment je pourrais supprimer eval et remplacer par quelque chose d'autre?

+11

Pourriez-vous donner le code de la façon dont vous utilisez 'eval'? –

+2

Restez à l'écart des belles femmes aussi. Les mêmes raisons. – kennebec

+0

À tout le moins serait bien si JSLint fourni une sorte de détail sur la raison pour laquelle il lance l'erreur. – drudge

Répondre

9

Au lieu de:

eval($.validator.format('Resources.message_{0}', functionResult)) 

il suffit d'utiliser:

Resources["message_" + functionResult] 

Tous les objets JavaScript sont des tableaux vraiment associatives (aka hash), et la syntaxe de point (a.b) est juste du sucre syntaxique pour la recherche quelque chose dans le hachage (a['b']). Donc vous n'avez pas du tout besoin de eval; Il suffit de créer la clé sous forme de chaîne et de rechercher votre valeur à l'aide de cette clé.

+1

J'allais poster exactement cela, mais je suis allé et construit un exemple d'abord: http://www.boogdesign.com/examples/array.html – robertc

8

http://blogs.msdn.com/b/ericlippert/archive/2003/11/01/53329.aspx

Dans la plupart des cas, eval est utilisé comme un marteau de forgeron swatting une mouche - il fait le travail, mais avec trop beaucoup de puissance. C'est lent, c'est lourd, et tend à amplifier les dégâts quand vous faites une erreur.

+1

Hmmm, Microsoft. Ce sont les mêmes personnes qui ne semblent pas capables d'utiliser 'strcpy' en toute sécurité, utilisant plutôt' strcpy_s' et al (qui est _far_ de safe, BTW), donc je ne suis pas sûr d'avoir mis trop de valeur dans leurs opinions :-) – paxdiablo

+2

opinions sont bien .. c'est leur code qui m'inquiète. – drudge

3

JS Lint incorpore ce que Douglas Crockford considère comme les meilleures pratiques pour JavaScript. L'une des fonctions qu'il déconseille fortement l'utilisation est eval. Je crois qu'il considère que c'est lent et peu sûr.

Il pourrait y avoir plusieurs alternatives potentielles, selon le code en question. Si vous souhaitez publier la section de votre code qui utilise eval, nous pouvons donner des conseils spécifiques.

+1

+1 pour ne pas avoir fait une assertion générale. 'eval' est aussi mauvais que' goto' ou plusieurs retours d'une fonction (c'est-à-dire, seulement mal si mal utilisé). En ce sens, les couteaux et les marteaux sont aussi maléfiques :-) Un bon artisan comprend et connaît les limites et les dangers de ses outils. – paxdiablo

3

Si vous essayez d'utiliser eval pour transformer des chaînes en objets JSON, essayez peut-être un JSON parser lib (je ne l'ai jamais utilisé mais il semble raisonnable).

5

C'est mal parce que cela vous permet d'exécuter une chaîne comme du code, et qui sait d'où vient cette chaîne ou ce qu'elle contient.

Et oui, 99,9% du temps, il existe de meilleures alternatives (ce que cela dépend exactement de ce que vous utilisez eval pour). Le reste 0,1% du temps, vous n'avez vraiment pas d'autre choix que d'utiliser eval, et dans de tels cas, vous devez être extrêmement prudent.

+0

Exactement. Si vous avez analysé ou vérifié que la chaîne est en sécurité, alors eval n'est pas un gros problème. C'est ainsi que fonctionne l'analyseur auquel je me suis connecté dans ma réponse. Pourquoi? Peut-être parce que 'eval' est écrit rapidement dans un langage de niveau inférieur à JavaScript, généralement en C ou C++. –

2

Je ne suis pas tout à fait clair sur ce que vous faites, mais il semble que
$('#divPresenter').html(eval($.validator.format('Resources.message_{0}', functionResult)));
peut être écrit comme
$('#divPresenter').html(Resources["message_" + functionResult]);