1

I have the following issue:

const value1 = "some value";
var   value2 = "some value";

console.log(window["value1"]); // undefined
console.log(window["value2"]); // some value

I know that const is block scoped and that is the reason I cannot access it through the window object. My question is, is there any way to access a const variable using only a string identifier.

If all I have access to is "value1", how do I get a handle on the actual value1? Is it even possible?

Frank
  • 2,050
  • 6
  • 22
  • 40
  • I'm not sure If I can use eval for this, but I would rather not use eval. – Frank Jul 07 '19 at 20:53
  • 4
    Yes, you could use `eval`, and yes you should not do that. Why not simply do `console.log(x == "value1" ? value1 : …)`? Why do you even *need* to access local variables by string, why don't you use an appropriate data structure (like a `Map` or an object)? – Bergi Jul 07 '19 at 20:54
  • 2
    If you must use a string to access a variable like that, why not just use an object? `const constants = { value1: "some value" };` Then you can get it using `console.log(constants["value1"])`. – Heretic Monkey Jul 07 '19 at 20:56
  • Possible dup of https://stackoverflow.com/questions/4174552/can-global-constants-be-declared-in-javascript – danh Jul 07 '19 at 20:57
  • @HereticMonkey, that's exactly what I did. I will use this for the time being. I'm still curious if it's possible, but probably not since it's block scoped. This may have been a hasty question. – Frank Jul 07 '19 at 21:42

1 Answers1

1

It appears that, block scope declarations, like let and const, are not added to the global object, meaning you can not access them through a property of window.

See this related question on Stack Overflow: https://stackoverflow.com/a/28776236/10965456

eval should work eval("values1"), as well as the Function constructor new Function("return value1")(), though I'm not sure why this is necessary. If you need to dynamically access certain values, use an array, object, or map instead.

ecc521
  • 576
  • 6
  • 14
  • 1
    Hey, that new Function("return value1")() method is pretty good. Do you know if it is very similar to eval? Of course, that's creating a function just to return the constant variable, which is probably not very efficient. Still, this has answered my question. This is another way to access a block scoped variable using a string. – Frank Jul 07 '19 at 21:43
  • The Function constructor is considered a form of eval when it comes to content security policies - and for good reason - passing unsanitized input to it can lead to arbitrary code execution. Adding script to the DOM can do the same thing. – ecc521 Jul 07 '19 at 21:53
  • Some info about eval and Function when it comes to security and performance: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#Do_not_ever_use_eval! – ecc521 Jul 07 '19 at 21:57
  • 1
    @Frank The `Function` constructor only works for global `const`/`let` variables, not for local block-scoped ones. And yes, it's very much the same as `eval` - don't use it. – Bergi Jul 08 '19 at 10:37
  • 1
    I did get it working for const variables in the global scope, but I think what I will use is an object like so: `{ "value1":value1 }` I am loading object constructors from a JSON file, so I have them in string format. I just need to get a handle on the actual constructor. – Frank Jul 10 '19 at 17:23
  • Probably the correct idea. Using an object or a map is ***far*** better than dynamically creating code. – ecc521 Jul 10 '19 at 17:27