Foro de elhacker.net

Programación => Desarrollo Web => Mensaje iniciado por: Drakaris en 24 Enero 2021, 14:21 pm



Título: equivalente a eval()? | javascript
Publicado por: Drakaris en 24 Enero 2021, 14:21 pm
Buenas, tengo un script hecho, que utiliza mucho la funcion eval(), pero no es nada recomendable, en estos casos. Como podría reemplazarlo?

trabajar con arrays/objetos, en este caso añadir:
Código
  1. eval("$HERO." + group + ".push('" + item.id.replace("Check","") + "')")
  2.  

eliminar objetos
Código
  1. eval("delete $HERO." + item[0]);
  2.  

operaciones
Código
  1. eval("$HERO.skills." + skill + "" + operator + "=" + countSkill);
  2.  

Código
  1. eval("$ELEMENTSPOINTS." + type + "." + element);
  2.  
En este caso quiero mostrar en el objeto $ELEMENTSPOINTS el elemento de su tipo, se que se puede hacerse así:
Código
  1. $ELEMENTSPOINTS[type];
  2.  
pero es solo para mostrar el subobjecto ELEMENTSPOINTS con todas sus propiedades, pero no el valor de uno en concreto.


Utilizo tanto el eval(), porque es dinamico, todos los eval estan dentro de una funcion que contiene parametros, cuyos parametros los utilizo en el eval(). Como lo hago sin utilizarlo?


Los objetos, son los siguientes:
Código
  1. $HERO={
  2.    name:null,
  3.    magic:[],
  4.    weapons:[],
  5.    gems:[],
  6.    skills:{
  7.        attack:0,
  8.        defenser:0,
  9.        speed:0
  10.    }
  11. }
  12. const $ELEMENTSPOINTS={
  13.    magic:{ // +
  14.        lightning:{
  15.            attack:10
  16.        },
  17.        ice:{
  18.            attack:4,
  19.            defenser:3
  20.        },
  21.        fire:{
  22.            attack:8
  23.        },
  24.        wind:{
  25.            defenser:2
  26.        }
  27.    },
  28.    weapons:{
  29.        sword:{
  30.            attack:5,
  31.            speed:1 // the speed substraction in the operation
  32.        },
  33.        shield:{
  34.            defenser:10,
  35.            speed:5
  36.        },
  37.        hatchet:{
  38.            attack:10,
  39.            speed:4
  40.        },
  41.        crossbow:{
  42.            attack:7,
  43.            speed:3
  44.        }
  45.    },
  46.    gems:{ // +
  47.        diamond:{
  48.            lightning:2,
  49.            ice:3,
  50.            fire:5,
  51.            wind:4
  52.        },
  53.        esmerald:{
  54.            lightning:2,
  55.            ice:3,
  56.            fire:5,
  57.            wind:4
  58.        },
  59.        ruby:{
  60.            lightning:3,
  61.            ice:2,
  62.            fire:3,
  63.            wind:2
  64.        },
  65.        sapphire:{
  66.            lightning:2,
  67.            ice:2,
  68.            fire:3,
  69.            wind:4
  70.        }
  71.    }
  72. }
  73.  

Un ejemplo de cuando utilizo eval:
Código
  1. ActionSkills = (type,element,operator)=>{
  2.        if(type != "gems"){
  3.            /*
  4.                 The buttons' group aren't gems, so all skills' type got by the specificed element's sub-objects are iterated, and each iteration
  5.                 gets skill's number and if the skill's type is 'speed' and operator is '+' the operator is become to '-'
  6.                 (because the speed substraction of speed's total count), else if the operator is '-', it is became in '+' (because the button is inactive).
  7.  
  8.                 Finally is add/substraction the value get with the skill's total specificed. Thanks to eval()
  9.  
  10.                 Also, if the button's group clicked is 'magic', apart from does previous it, this runs the function ActionGems()
  11.             */
  12.            for(skill in eval("$ELEMENTSPOINTS." + type + "." + element)){
  13.                countSkill = eval("$ELEMENTSPOINTS." + type + "." + element + "." + skill);
  14.                //console.log(skill + ":" + countSkill);
  15.                (skill == "speed" && operator == " + ")?(operator = "-"):(skill == "speed" && operator == "-")?(operator = " + "):null;
  16.                eval("$HERO.skills." + skill + "" + operator + "=" + countSkill);
  17.            }
  18.  
  19.            (type == "magic")?ActionGems(type,element,operator):null;
  20.        }else{
  21.            /*
  22.                 As are gems, the operation is different. So this executes the function ActionGems()
  23.             */
  24.            ActionGems(type,element,operator);
  25.        }
  26.    }
  27.  

Gracias de antemano


Título: Re: equivalente a eval()? | javascript
Publicado por: @XSStringManolo en 24 Enero 2021, 17:06 pm
eval("$HERO.skills." + skill + "" + operator + "=" + countSkill);

Para qué quieres el eval?
$HERO.skills[skill] + = countSkill;

Si quieres usar distintos operadores usas una función.
Código
  1. function operar(operacion) {
  2.  switch(operacion) {
  3.    case "sumar":
  4.      $HERO.skills[skill] += countSkill;
  5.    break;
  6.  
  7.    case "restar":
  8.      $HERO.skills[skill] -= countSkill;
  9.    break;
  10.  }
  11. }
  12.  
  13. operar("sumar");


También deberías usar template strings por no volverte loco con tanta coma y +
eval(`$HERO.skills.${skill}${operator}=${countSkill}`);


Título: Re: equivalente a eval()? | javascript
Publicado por: MinusFour en 24 Enero 2021, 19:47 pm
Todos estos con la excepción de uno se pueden remplazar con la notación en corchetes:

Código
  1. eval("$HERO." + group + ".push('" + item.id.replace("Check","") + "')")
  2.  

Código
  1. $HERO[group].push(item.id.replace("Check", ""));

Código
  1. eval("delete $HERO." + item[0]);
  2.  

Código
  1. delete $HERO[item[0]];

Código
  1. eval("$ELEMENTSPOINTS." + type + "." + element);
  2.  

Código
  1. $ELEMENTSSPOINTS[type][element];

El otro también necesita notación en corchetes pero necesitas manejar los casos de operación:

Código
  1. if(operator === '+'){
  2.    $HERO.skills[skill] += countSkill;
  3. } else if (operator === '-') {
  4.    $HERO.skills[skill] -= countSkill;
  5. }

O el switch como lo menciona @XSSStringManolo


Título: Re: equivalente a eval()? | javascript
Publicado por: Drakaris en 25 Enero 2021, 00:17 am
Muchisimas gracias a los dos! Me a funcionado muy bien.
@XSStringManolo, no cai en que podia hacerlo de esa manera.