window[name] equivalent to dynamically access const and let declarations

javascript const function
javascript const
const array javascript
javascript const
javascript constants best practices
let and const
javascript const function example
const java

The old style JavaScript var declaration outside of a closure is global (top-level scope) and can be accessed in a browser from the window object. For example, the declaration var x = 3; can be accessed with window['x'].

How do you similarly access a const or let declaration given the name (string) of the declaration?

var x = 3;
const y = 7;
let z = 21;

console.log('x = ' + window['x']);  //x = 3
console.log('y = ' + window['y']);  //y = undefined
console.log('z = ' + window['z']);  //z = undefined

For the above example, how do you get the values 7 and 21 for "y" and "z" instead of undefined?

Fiddle with the code: https://jsfiddle.net/g78ah6we/

Edits (notes added for clarity): 1. While not typical, there are use cases, such as from within a library, that it's necessary to access a declaration based only on the name of the declaration. 2. Only read access is needed (none of the declarations will be modified). 3. The window object is mentioned just to show the old way, but this question is not actually about using the window object (or the global object).

Using indirect calls to eval

Accessing global const and let definitions can be done using an indirect call to eval. That is make eval the result of a comma separated expression or assign it to a variable first. If the syntactic access is not directly to the built-in eval function it's an indirect access, and indirect access executes in global scope.

You can also set global let variables by building script to perform the setting operation.

"use strict";
let myVar =  "global variable myVar";

console.log(  myVar);

(function myLibrary() {

    const myVar = "local variable myVar";

    const indirectEval = eval;
    var varName = "myVar";

    console.log( eval(varName));   // direct call uses local scope
    console.log( indirectEval(varName));  // indirect call uses global scope

    var result = "\"updated global variable even though shadowed\"";
    var js = varName + '=' + result;
    indirectEval(js);

    // but trying to define a new let variable doesn't attach to global scope

    var js2 ='let letVar2 = "let variable two"';
    indirectEval( js2);
})();
console.log( myVar)

console.log( "letVar2: " + typeof letVar2);

const, For example, the declaration var x = 3; can be accessed with window['x'] . How do you similarly access a const or let declaration given the name (string) of the  Accidentally used name (with no previous declaration) in JSX - compiled but failed at runtime. {name} If it were declare const name: void instead of declare const name: never, the above would properly fail to compile. Is there a reason this must be never?

Both let and const are block scoped.

In contrast, the variable declarations without var keyword creates variables in the outermost functional scope bubble. In browsers, the outermost functional scope is controlled by the window object.

What the window object doesn't control is the outermost block scope.

If your code doesn't work without being able to access variables in the window[nn] pattern, there definitely is a design issue in it.

Variables and assignment • JavaScript for impatient programmers, Global constants do not become properties of the window object, unlike var variables. The const declaration creates a read-only reference to a value. A constant cannot share its name with a function or a variable in the same scope. equally well with let to declare a block scoped non const variable) let  The other difference between var and let is that the latter is initialized to a value only when a parser evaluates it (see below). Just like const the let does not create properties of the window object when declared globally (in the top-most scope). An explanation of why the name "let" was chosen can be found here. Scoping rules

I've marked traktor53's answer as accepted and upvoted it because it contains the technical core of the solution.

In case it's helpful for anyone, here's a solution wrapped up into a function that prevents executing code in the declaration.

var x = 3;
const y = 7;
let z = 21;
const malware = 'alert("Game over.");';

function getDeclaration(name) {
   var identifierPattern = /^[_$a-zA-Z][_$a-zA-Z0-9]*$/;
   var topLevelGet = (null, eval);
   return identifierPattern.test(name) && topLevelGet('typeof ' + name) === 'number' ?
      topLevelGet(name) : null;
   }

console.log(getDeclaration('x'));        //output: 3
console.log(getDeclaration('y'));        //output: 7
console.log(getDeclaration('z'));        //output: 21
console.log(getDeclaration('bogus'));    //output: null
console.log(getDeclaration('malware'));  //output: null
console.log(getDeclaration('if'));       //EXCEPTION: unexpected keyword

Notes:

  1. Be aware that the identifierPattern regex is very simplistic (does not handle all valid characters and trips up on reserved words... as traktor53 pointed out, "This is more complicated than you might think").
  2. Change 'number' to 'object' or whatever is appropriate for your needs (for simplicity in the original question I used examples with numbers, but my real use case actually looks for objects).

Fiddle with the code: https://jsfiddle.net/g78ah6we/6/

${"dynamic" + $i} variable names in javascript - JavaScript, let declares mutable variables. const declares constants (immutable variables). The scope of a variable is the region of a program where it can be accessed. Consider the 10.6 Terminology: static vs. dynamic They are created in the top level of a script, via var and function declarations. But the prefix “ window. Start studying CS 1337 Ch. 14 Review Questions. Learn vocabulary, terms, and more with flashcards, games, and other study tools.

ES6 in Action: Enhanced Object Literals, However I can't work out how to create a dynamic variable name in javascript. I basically need to pass these variables into an ajax GET request so I can use them in the requested var o = new Object; o.property = "value"; // is functionally equivalent to o["property"] = "value"; window['divEmail'] is the same as window. This might cause a lot of bugs in your code. This is why the let and const is necessary. LET. let is preferred for variable declaration now. It's no surprise as it comes as an improvement to the var declarations. It also solves this problem that was raised in the last subheading. Let's consider why this is so.

JavaScript const, ES6 code const a = 1, b = 2, c = 3; obj = { a b c }; // obj.a = 1, obj.b = 2, obj.c = 3 Object Method Definition Shorthand Object keys can be dynamically assigned in ES6 by placing an can create a variable with the same name as an equivalent object property. let a, b, c; ({ a, b, c } = myObject); // WORKS. Evaluating such an expression must be done at the location where it is mentioned. Anything else would be confusing. That explains why class declarations are not activated early. 10.8.4 var: hoisting (partial early activation) var is an older way of declaring variables that predates const and let (which are preferred now).

Constants - PHP: Constants, Declaring a variable with const is similar to let when it comes to Block Scope. The x declared in the block, in this example, is not the same as the x declared  This PR adds new typing constructs that enable static validation of code involving dynamic property names and properties selected by such dynamic names. For example, in JavaScript it is fairly common to have APIs that expect property names as parameters, but so far it hasn't been possible to express the type relationships that occur in those APIs.

Comments
  • Possible duplicate of Do let statements create properties on the global object?
  • @CertainPerformance That question is about if they are on the global object, and we already know they are not. This questions is about how to workaround the issue.
  • They're not on the global object, so it's impossible to access them through window.y and window.z - it seems to be the same issue to me?
  • It looks like the only correct answer to this question will involve eval, yet the supposed duplicate does not even mention eval (in the question or any of the answers). It's clear some people thought that this question was unanswerable.
  • True, "eval is evil", but it may very well be the only solution. Is the advantage of the indirect use of (0,eval)('x') over the direct use of eval('x') just to avoid scope confusion? jsfiddle.net/g78ah6we/3
  • Yes - see the updated answer for a fuller discussion.
  • "recommend finding alternatives" The library already has an API call to register a context (required when used with WebPack), but forcing developers to use a hard to explain API call just to try out the library would be undesirable.
  • there definitely is a design issue in it... if it's all your own code. On the other hand, if a library reads an attribute from a DOM element that declares a callback, would you force the library user to register (bind) their functions?