equivalente a eval()? | javascript

Iniciado por Drakaris, 24 Enero 2021, 14:21 PM

0 Miembros y 1 Visitante están viendo este tema.

Drakaris

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 (javascript) [Seleccionar]

eval("$HERO." + group + ".push('" + item.id.replace("Check","") + "')")


eliminar objetos
Código (javascript) [Seleccionar]

eval("delete $HERO." + item[0]);


operaciones
Código (javascript) [Seleccionar]

eval("$HERO.skills." + skill + "" + operator + "=" + countSkill);


Código (javascript) [Seleccionar]

eval("$ELEMENTSPOINTS." + type + "." + element);

En este caso quiero mostrar en el objeto $ELEMENTSPOINTS el elemento de su tipo, se que se puede hacerse así:
Código (javascript) [Seleccionar]

$ELEMENTSPOINTS[type];

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 (javascript) [Seleccionar]

$HERO={
   name:null,
   magic:[],
   weapons:[],
   gems:[],
   skills:{
       attack:0,
       defenser:0,
       speed:0
   }
}
const $ELEMENTSPOINTS={
   magic:{ // +
       lightning:{
           attack:10
       },
       ice:{
           attack:4,
           defenser:3
       },
       fire:{
           attack:8
       },
       wind:{
           defenser:2
       }
   },
   weapons:{
       sword:{
           attack:5,
           speed:1 // the speed substraction in the operation
       },
       shield:{
           defenser:10,
           speed:5
       },
       hatchet:{
           attack:10,
           speed:4
       },
       crossbow:{
           attack:7,
           speed:3
       }
   },
   gems:{ // +
       diamond:{
           lightning:2,
           ice:3,
           fire:5,
           wind:4
       },
       esmerald:{
           lightning:2,
           ice:3,
           fire:5,
           wind:4
       },
       ruby:{
           lightning:3,
           ice:2,
           fire:3,
           wind:2
       },
       sapphire:{
           lightning:2,
           ice:2,
           fire:3,
           wind:4
       }
   }
}


Un ejemplo de cuando utilizo eval:
Código (javascript) [Seleccionar]

ActionSkills = (type,element,operator)=>{
       if(type != "gems"){
           /*
               The buttons' group aren't gems, so all skills' type got by the specificed element's sub-objects are iterated, and each iteration
               gets skill's number and if the skill's type is 'speed' and operator is '+' the operator is become to '-'
               (because the speed substraction of speed's total count), else if the operator is '-', it is became in '+' (because the button is inactive).

               Finally is add/substraction the value get with the skill's total specificed. Thanks to eval()

               Also, if the button's group clicked is 'magic', apart from does previous it, this runs the function ActionGems()
           */
           for(skill in eval("$ELEMENTSPOINTS." + type + "." + element)){
               countSkill = eval("$ELEMENTSPOINTS." + type + "." + element + "." + skill);
               //console.log(skill + ":" + countSkill);
               (skill == "speed" && operator == " + ")?(operator = "-"):(skill == "speed" && operator == "-")?(operator = " + "):null;
               eval("$HERO.skills." + skill + "" + operator + "=" + countSkill);
           }

           (type == "magic")?ActionGems(type,element,operator):null;
       }else{
           /*
               As are gems, the operation is different. So this executes the function ActionGems()
           */
           ActionGems(type,element,operator);
       }
   }


Gracias de antemano
Lo increible, no es lo que ves, sino como es

@XSStringManolo

#1
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 (javascript) [Seleccionar]
function operar(operacion) {
 switch(operacion) {
   case "sumar":
     $HERO.skills[skill] += countSkill;
   break;

   case "restar":
     $HERO.skills[skill] -= countSkill;
   break;
 }
}

operar("sumar");



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

MinusFour

Todos estos con la excepción de uno se pueden remplazar con la notación en corchetes:

Cita de: Drakaris en 24 Enero 2021, 14:21 PM
Código (javascript) [Seleccionar]

eval("$HERO." + group + ".push('" + item.id.replace("Check","") + "')")


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

Cita de: Drakaris en 24 Enero 2021, 14:21 PM
Código (javascript) [Seleccionar]

eval("delete $HERO." + item[0]);

Código (javascript) [Seleccionar]
delete $HERO[item[0]];

Cita de: Drakaris en 24 Enero 2021, 14:21 PM
Código (javascript) [Seleccionar]

eval("$ELEMENTSPOINTS." + type + "." + element);

Código (javascript) [Seleccionar]
$ELEMENTSSPOINTS[type][element];

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

Código (javascript) [Seleccionar]

if(operator === '+'){
    $HERO.skills[skill] += countSkill;
} else if (operator === '-') {
    $HERO.skills[skill] -= countSkill;
}


O el switch como lo menciona @XSSStringManolo

Drakaris

Muchisimas gracias a los dos! Me a funcionado muy bien.
@XSStringManolo, no cai en que podia hacerlo de esa manera.
Lo increible, no es lo que ves, sino como es