0

This article is clear that we shouldn't use eval().

https://24ways.org/2005/dont-be-eval

But I've failed to implement the suggested alternative.

A simple version of what I'm doing:

var list = $('ul.plain-list li');
$('.search-filter button').each(function(){
    var d = $(this).data('filter');
    $(this).text(eval(d).length);
});

The value of the variable d matches the names of a set of other variables, for example list. I'm using eval() to marry these two things up, which is very effective, but it looks like I shouldn't be doing it.

What is the correct way to do the above without using eval()?

Edit: I'm not generating variable variables! It looks like I could be using an array or dictionary, but that seems overly-complex, the above code is working very well and is so lightweight.

Edit2: I definitely appreciate the answers, but what I'm thinking is that my usage of eval() is so specific, just a single string from a piece of static HTML, that the security issues mentioned in the article aren't relevant. Is that fair to say?

Edit3: Still struggling with this I'm afraid. Here's my exact code, if anyone can rewrite it I would be very appreciative.

var all = $('ul.plainList li');
var stories = $('ul.plainList li:not(.type-sjn)');
var sjn = $('ul.plainList li.type-sjn');
$('.search-filter button').each(function(){
    var d = $(this).data('filter');
    $(this).find('span').text(eval(d).length);
});

In case it's not clear, the values of data-filter exactly match the var names all, stories, sjn.

What the code does is gets the count of different types of posts, and inserts this count into a button which corresponds to each post type.

byzantine cucumber
  • 531
  • 1
  • 5
  • 12
  • 1
    What sort of variable type is `d`? Can you just do `.text(d.length)`? – CertainPerformance Jul 11 '19 at 11:49
  • 1
    @CertainPerformance — "The value of the variable d matches the names of a set of other variables, for example list" … so `d` is a string containing the name of a variable. `d.length` would give the `4` (the length of `"list"`) and not the length of whatever the variable `list` is. – Quentin Jul 11 '19 at 11:50
  • @Carcigenicate No, I'm not generating dynamic variable names. I'm referring to one set of variables, by name, from the string values of another set of variables.. if that makes sense :-) – byzantine cucumber Jul 11 '19 at 11:57
  • @byzantinecucumber I still don't entirely understand what you're trying to do, but it still sounds like you should be using an object as a map here to map names to the "set of variables". – Carcigenicate Jul 11 '19 at 12:02
  • Using objects as maps is lightweight; arguably more lightweight than eval depending on what your definition of lightweight is. It really just adds a single line when you declare the map like `var lookup_map = {};` then `lookup _map[var_name] = some _vars` to add, and `lookup_map[var _name]` to replace eval. – Carcigenicate Jul 11 '19 at 12:04
  • Dictionaries in javascript are lightweight. The most syntactically lightweight implementation of a dictionary is to use a plain object as a dictionary – slebetman Jul 11 '19 at 12:06
  • 1
    @byzantinecucumber I know you say you're not generating variable variables but the linked duplicate answer is still the **real correct answer** to your question – slebetman Jul 11 '19 at 12:08
  • @Carcigenicate Not really, I'd need to be pushing the variables and rewrite a bunch of stuff. This is 6 characters of code. I know I'm splitting hairs, it's not a problem, I'm just a little surprised I need to change that much to do what I'm achieving with `eval()`. – byzantine cucumber Jul 11 '19 at 12:08
  • I don't understand why you're saying you need to rewrite a lot. If you already have a set of variables then all you need to do is add them to a pair of braces `{}` – slebetman Jul 11 '19 at 12:09
  • @slebetman Hence my confusion! I thought there might be a way of achieving the same thing without having to change the type of variable I'm using. Apparently not. – byzantine cucumber Jul 11 '19 at 12:10
  • @slebetman I'll need to push them. I'm not trying to suggest it's a lot of work, but my code works just fine without having to restructure my variables. – byzantine cucumber Jul 11 '19 at 12:11
  • 1
    But anyone changing the value of `data-filter` is able to force you to eval their code in your scope. If you're protecting your code inside an IIFE (so external scripts cannot hijack your variables) then that makes the IIFE protection useless. If you're not protecting your code against external scripts then it doesn't matter – slebetman Jul 11 '19 at 12:20
  • No that's fair enough. I'm still surprised I have to resort to an array, but that's ok! Thanks for your input. – byzantine cucumber Jul 11 '19 at 12:23

0 Answers0