Home > Enterprise >  JavaScript making a String into a variable name without eval
JavaScript making a String into a variable name without eval

Time:08-01

I wanted to get the value of an HTML input by using the dollar ($) sign, since I have to make a String the only way I can think of is using the eval() function, but since it is not recommended I wanted to know which alternative could I use.

Basically here ${player} can be "player1" or "player2":

eval(`${player}NameInput`)

So that it access one or the other of this input elements:

const player1NameInput = document.getElementById("name1")
const player2NameInput = document.getElementById("name2")

Here is the code with more context:

const player1NameInput = document.getElementById("name1")
const player2NameInput = document.getElementById("name2")

const player = event.target.id.slice(7,14) // Can be "player1" or "player2"
let name = document.getElementById(`${player}-name`) // A label
name.textContent = eval(`${player}NameInput`).value   ": "
eval(`${player}NameInput`).value = ""

I've tried the function approach and the window[variable] approach but I couldn't make them work, I also have the feeling that there must be a simpler approach.

In the function approach I did:

Function('"use strict"; return '   `${player}NameInput`)()

Which gives me this error:

Uncaught ReferenceError: player1NameInput is not defined
    at eval (eval at changeName (script.js:158:21), <anonymous>:3:15)
    at HTMLButtonElement.changeName (script.js:158:77)

Thanks!

CodePudding user response:

If you really need to use string interpolation to get the value, you can put the values in an object:

const players =
{
  player1NameInput: document.getElementById("name1"),
  player2NameInput: document.getElementById("name2")
};

const player = event.target.id.slice(7,14); // Can be "player1" or "player2"
let name = document.getElementById(`${player}-name`); // A label
name.textContent = players[`${player}NameInput`].value   ": ";
players[`${player}NameInput`].value = '';

CodePudding user response:

Use an object to store them by name, instead of multiple variables.

const nameInputs = {
  player1: document.getElementById("name1"),
  player2: document.getElementById("name2"),
}
const nameLabels = {
  player1: document.getElementById("player1-name"),
  player2: document.getElementById("player2-name"),
};

const player = event.target.id.slice(7,14) // Can be "player1" or "player2";
nameLabels[player].textContent = nameInputs[player].value   ": ";
nameInputs[player].value = "";

Even easier to access (in general) might be an array, with index 0 for player 1 and index 1 for player 2. This will make for simpler code when iterating all elements or toggling between them.

  • Related