0

When I run the following code I get the error: "Uncaught ReferenceError: testVariable is not defined"

eval("var testVariable = 0");
console.log(testVariable);

However, when I run this in for example CodeSnippets it works perfectly fine. Hence I am very confused.

My index.html simply has an import: <script type="module" src ="./classes.js"></script>. Do note that I have simplified the issue down to it's concepts as I am actually using eval() to dynamically create variables.

Edited to add something closer to my actual code as commenters are asking why I want to dynamically make variables:

variables.js

import { exampleClass } from './classes.js';
import{createExampleClasses} from './classes.js';

export let classesArray =[];
createExampleClasses(); 

classes.js

import { classesArray } from "./variables.js";

let WaitForElement = element =>{if (typeof element !== "undefined"){ console.log(element); }else{setTimeout(WaitForElement(),250)}};

export class exampleClass{
    constructor(name){
        this.name=name;
    }
}

export function createExampleClass(){
    let exampleObject = "exampleObject"+classesArray.length.toString();
    eval( "let "+ exampleObject + " = new exampleClass(\"random\");");
    classesArray.push(eval(exampleObject));
}   

export function createExampleClasses(){
    createExampleClass();
    createExampleClass();
}
yjzhou
  • 67
  • 1
  • 8
  • 3
    Suggestion: don't. I've yet to see any compelling reason to do this. And I sincerely doubt you'll offer one. – VLAZ Mar 02 '23 at 11:45
  • 2
    *"dynamically create variables"*: You should dynamically create **object keys**, not variables. – trincot Mar 02 '23 at 11:46
  • 2
    1. drop the `type=module`. 2. eval is evil. [don't](https://stackoverflow.com/a/1832957/4935162) [use](https://stackoverflow.com/questions/86513/why-is-using-the-javascript-eval-function-a-bad-idea) [eval](https://javascriptweblog.wordpress.com/2010/04/19/how-evil-is-eval/) – Yarin_007 Mar 02 '23 at 11:48
  • @VLAZ I've updated the question, hope this is a compelling reason? – yjzhou Mar 02 '23 at 11:54
  • Modules automatically run in [strict mode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode). When in strict mode, `eval()` [doesn't "leak"](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode#non-leaking_eval) variables created within it to the surrounding scope. Use an object if you want to create "dynamic" bindings/variables, as shown here: ["Variable" variables in JavaScript](https://stackoverflow.com/q/5187530) – Nick Parsons Mar 02 '23 at 11:55
  • 1
    No, it is not a compelling reason. – trincot Mar 02 '23 at 11:55
  • @NickParsons thank you very much for the link! Also a more general question, why is my question getting downvoted? – yjzhou Mar 02 '23 at 11:59
  • 3
    @yjzhou not at all? You want to use `eval` ***ONLY*** so you can add something to an array the *entire* body of `createExampleClass` could be `classesArray.push(new exampleClass("random"));` there is no reason to dynamically create a variable which isn't even used other than for reading. The code could have also been `let exampleObject = new exampleClass("random"); classesArray.push(exampleObject);` without the `eval`. So, you failed to convince me. – VLAZ Mar 02 '23 at 11:59
  • @yjzhou You're welcome - not sure why it has been given a dv. Perhaps people think you didn't search thoroughly enough before asking, or they think it's unclear or not useful. But personally, I think your question about why eval works in one situation and not the other is interesting, and not the easiest thing to find without prior knowledge of strict-mode, modules and how eval behavior changes in strict mode. The whole topic of dynamic variables has been covered a number of times though, so I'm guessing that's where the dv is from. – Nick Parsons Mar 02 '23 at 12:10
  • @NickParsons thank you for your kind words. Honestly I'm a little sad cos I have anxiety and am scared to ask StackOverflow questions. I really did do research, and a lot of what I searched seemed to imply that the eval() would work. I know that my anxiety is my issue, but honestly as a self-taught programmer who is relatively new to javascript, I feel a lot of anxiety when I want to ask questions on SO. – yjzhou Mar 02 '23 at 12:15
  • 1
    @yjzhou You’re not alone. Stack Overflow has been criticised for being unwelcoming in the past. I wouldn’t take the dvs too personally (maybe next time you might want to include some links to some posts you read to show others you’ve searched around?) The people who float around these questions tend to be JS gurus and know their stuff inside out, so something they think should be obvious might not be as obvious to someone who’s new/mid level. – Nick Parsons Mar 02 '23 at 12:43
  • 1
    For people interested in technical reasons rather than opinion it's a shame the question was closed. If you call `eval("let name = expresssion;")`, `eval` creates the variable `name` in block scope, the evaluation context of `eval`. When `eval` returns, that execution context disappears. So the declaration of `let exampleObject = ...` goes out of scope when it returns and is not longer accessible. Not using `eval` remains important but is not an answer to the question. – traktor Mar 02 '23 at 13:07

0 Answers0