0

Since eval is not good with the performance, I would like to know if there is any way to remove the eval in this code for some other code. The objective is to be able to create SVG elements via a function. The current method is by using an eval to create the element.

function createrect(createrectvar1 , createrectvar2 , createrectvar3 , createrectvar4 , createrectvar5 , createrectvar6 , createrectvar7 , createrectvar8 , createrectvar9 , createrectvar10 , createrectvar11) {
/** id , x , y , rx , width , height , fill , stroke ,  stroke w , svgid , onclick **/
if (createrectvar11 == "_") {
eval(createrectvar1 + " = document.createElementNS('http://www.w3.org/2000/svg', 'rect') ; " + createrectvar1 + ".setAttribute('x' , " + createrectvar2 + ") ; " + createrectvar1 + ".setAttribute('y' , " + createrectvar3 + ") ; " + createrectvar1 + ".setAttribute('rx' , " + createrectvar4 + ") ; " + createrectvar1 + ".setAttribute('width' , " + createrectvar5 + ") ; " + createrectvar1 + ".setAttribute('height' , " + createrectvar6 + ") ; " + createrectvar1 + ".setAttribute('fill' , '" + createrectvar7 + "') ; " + createrectvar1 + ".setAttribute('stroke' , '" + createrectvar8 + "') ; " + createrectvar1 + ".setAttribute('stroke-width' , '" + createrectvar9 + "') ; " + createrectvar10 + ".appendChild(" + createrectvar1 + ") ; ") ;
} else {
eval(createrectvar1 + " = document.createElementNS('http://www.w3.org/2000/svg', 'rect') ; " + createrectvar1 + ".setAttribute('x' , " + createrectvar2 + ") ; " + createrectvar1 + ".setAttribute('y' , " + createrectvar3 + ") ; " + createrectvar1 + ".setAttribute('rx' , " + createrectvar4 + ") ; " + createrectvar1 + ".setAttribute('width' , " + createrectvar5 + ") ; " + createrectvar1 + ".setAttribute('height' , " + createrectvar6 + ") ; " + createrectvar1 + ".setAttribute('fill' , '" + createrectvar7 + "') ; " + createrectvar1 + ".setAttribute('stroke' , '" + createrectvar8 + "') ; " + createrectvar1 + ".setAttribute('stroke-width' , '" + createrectvar9 + "') ; " + createrectvar1 + ".setAttribute('onclick' , '" + createrectvar11 + "()') ; " + createrectvar10 + ".appendChild(" + createrectvar1 + ") ; ") ;
}
}
Theodore
  • 283
  • 1
  • 3
  • 15
Tom Lee
  • 360
  • 1
  • 3
  • 10
  • 3
    Start with [“Variable” variables in Javascript?](https://stackoverflow.com/q/5187530) - just don't have dynamic variables. Use an object with properties. Then just use that normally in your code instead of generating code to run. – VLAZ May 18 '21 at 11:22
  • 2
    You know what these `eval`s do? If yes you can just take the content from within and convert it into actual code. I don't see why this was done with `eval` in the first place. – Detonar May 18 '21 at 11:34
  • @Detonar because of `createrectvar1` which is an arbitrary variable name. For some reason. – VLAZ May 18 '21 at 11:51
  • 1
    "For some reason" is exactly the point here. You need to find out why it's arbitrary. Maybe this variable is defined and used somewhere else in the code. Removing `eval` here without understanding the purpose of `createrectvar1` outside of `createrect` sounds like a gamble here. – Detonar May 18 '21 at 12:24
  • @Detonar The correct thing to do in that case would be to stop using variable variables, but hey… – deceze May 18 '21 at 12:26
  • @deceze - True, but sometimes you just end up being responsible for code you never wrote yourself in the first place. I agree that refactoring and removing odd code sections like this should be done but i want to point out that it still holds a certain risk. – Detonar May 18 '21 at 12:30
  • 1
    What's createrectvar1 ? an element on the DOM or what else? – Vixed May 18 '21 at 12:46
  • Just a string that is passed in via the function. – Tom Lee May 18 '21 at 12:49

2 Answers2

3

I don't see the point in using eval(). Here I have a function createRect() that will create a rect element in a svg element.

const createRect = (svgElm, id, height = 1, width = 1, fill = 'blue') => {
  let rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
  rect.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
  rect.setAttribute('height', height);
  rect.setAttribute('width', width);
  rect.setAttribute('fill', fill);
  rect.setAttribute('x', 0);
  rect.setAttribute('y', 0);
  svgElm.appendChild(rect);
};

let svg01 = document.getElementById('svg01');
createRect(svg01, 12, 100, 50);
<svg xmlns="http://www.w3.org/2000/svg" id="svg01"></svg>
chrwahl
  • 8,675
  • 2
  • 20
  • 30
  • I am using js to create svg graphics, if for every rectangle I have to write this amount of code, there would be a lot of repetitive code. Hence, I decided to have a function to help me create rectangles in 1 line of code / rectangle. – Tom Lee May 18 '21 at 12:47
  • @Tom And that's what this function here does too, just in a sane way, without `eval`. It's unclear whether your comment is meant as a critique, or just an explainer… – deceze May 18 '21 at 12:49
  • @Tom Then skip the `svgElm` and just `return rect` from the function, and then do with it in the caller whatever you want. – deceze May 18 '21 at 12:54
  • @TomLee the problem are not the lines, but the bytes... this code is lighter than yours. – Vixed May 18 '21 at 12:54
1

I really don't like the approach, but I'm sure you're looking for something like this:

function createrect(createrectvar1, createrectvar2, createrectvar3, createrectvar4, createrectvar5, createrectvar6, createrectvar7, createrectvar8, createrectvar9, createrectvar10, createrectvar11) {
    /** id, x, y, rx, width, height, fill, stroke,  stroke w, svgid, onclick **/
    let rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect'); rect.setAttribute('id',createrectvar1); rect.setAttribute('x',createrectvar2); rect.setAttribute('y',createrectvar3) ; rect.setAttribute('rx',createrectvar4) ; rect.setAttribute('width',createrectvar5) ; rect.setAttribute('height',createrectvar6) ; rect.setAttribute('fill',createrectvar7) ; rect.setAttribute('stroke',createrectvar8) ; rect.setAttribute('stroke-width',createrectvar9);
    if (createrectvar11 != '_') rect.setAttribute('onclick',createrectvar11);
    document.getElementById(createrectvar10).appendChild(rect);
}
Vixed
  • 3,429
  • 5
  • 37
  • 68