1 of 13

[[VarNames]],

What Is It Good For?

"Well, I think absolutely nothing."

– Shu-yu Guo (Google), Feb Apr 2024 TC39

2 of 13

What is [[VarNames]]

So,

  • In general, we disallow lexical and var bindings to share the same name in the same scope
  • The global scope is special
    • It's open, unlike a function scope. You can have multiple <script> tags processed at different times adding things to the same global scope
    • vars are also properties on globalThis

3 of 13

What is [[VarNames]]

<script>

var x;

</script>

<script>

let x;

</script>

This is disallowed.

Fine. Good. Whatever.

4 of 13

What is [[VarNames]]

<script>

Object.defineProperty(

globalThis, 'x',

{ value:42, configurable:false });

</script>

<script>

let x;

</script>

This is also disallowed.

…Okay. Sure. Seems fine.

5 of 13

What is [[VarNames]]

<script>

eval('var x');

</script>

<script>

let x;

</script>

This is also disallowed.

Seems fine, except…

how do you implement it?

6 of 13

Remember the direct eval var semantics

  • Adds a delete-able binding
  • When at the global scope, adds a property to globalThis
  • Upshot: adds a configurable property to globalThis
  • But wait, this is allowed:

<script>

globalThis.x = 42;

</script>

<script>

let x;

</script>

7 of 13

[[VarNames]] distinguishes eval-introduced vars

So [[VarNames]] is a list on the global environment whose sole purpose is to distinguish sloppy-direct-eval-introduced vars from ordinary configurable properties

  • Annoying to understand
  • Annoying to implement
  • Complexity in service of no one: what are the use cases here?

8 of 13

Are there actual use cases?

  • You shouldn't be using sloppy direct eval to introduce global vars
  • You can redeclare sloppy direct eval introduced global vars: you just have to delete them first!

9 of 13

Current semantics

In the global scope,

  • It is a SyntaxError to redeclare a let or const with a like-named let or const
  • It is a SyntaxError to redeclare a non-configurable property with a like-named let or const
  • It is a SyntaxError to declare a let or const with a name present in [[VarNames]]

10 of 13

Proposal

In the global scope,

  • It is a SyntaxError to redeclare a let or const with a like-named let or const
  • It is a SyntaxError to redeclare a non-configurable property with a like-named let or const
  • It is a SyntaxError to declare a let or const with a name present in [[VarNames]]

11 of 13

Upshot

<script>

eval('var x');

</script>

<script>

let x;

</script>

This is now allowed.

let x will shadow.

12 of 13

Updates from last time

13 of 13

Stage 2.7?