You don't need eval to create objects or methods. This is perfectly valid JS code:
js> var initial=1
js> var increment=3
js> var counter={
count:initial,
advance:function(){
this.count += increment
return this.count
}
}
js> counter.advance()
4
js> counter.advance()
7
js> counter.advance()
10
As you see, I have actually run it in an interactive interpreter to verify that it's good.
At the time of counter creation, initial and increment are normal variables whose value gets embedded in the counter object. They could be user-supplied numbers, no problem.
The whole code can be packaged as a function with two parameters and called 100 times to create 100 different counters, it will work as expected.
edit
Okay, I actually lied a bit. It's not the value of increment which is embedded in the counter but a reference to that variable. Changing increment changes behavior of counter:
js> increment=5
5
js> counter.advance()
15
js> counter.advance()
20
But if you create a function make_counter, each execution of make_counter gets its own copy of increment. Therefore each created counter will use its own copy of increment and the counters will be independent of each other. Try it, it works.
It's a bit like using goto.
There is nothing inherently wrong about using eval or goto. Just think about how you are using it. In terms of eval, where the data comes from, or importantly, ways in which the data could come from somewhere undesirable.
Don't go using it for just parsing a JSON string, all modern browsers support the JSON.parse (https://caniuse.com/#search=JSON.parse) method which will not risk executing code.
The most prominent example of a bad idea for javascript eval usage of course is that you would absolutely not want to blindly eval any data that was passed in to the server by the user and then spat back out to their browser because you can not be sure that data did actually come from the user and not a malicious actor, in other words, this is a super bad idea...
<script type="text/javascript">
eval('<?php echo $_REQUEST['EvilEval']; ?>');
</script>