Because the declaration itself is hoisted. The TDZ only delays
*initialization*, not *declaration*.

- For `var`, the declaration is hoisted *and* it's automatically
initialized to `undefined` before executing any body code.
- For `function foo() { ... }`, the declaration is hoisted *and* the
value is automatically initialized to a new function object
encapsulating the function's body before executing any body code.
- For all other types, the declaration is hoisted, but it is *not*
possible to initialize it yet. It's initialized to `undefined` for
`let value;` when that statement is executed, the relevant function
object for `class Foo`, the RHS value for `let value = expr`/`const
value = expr`, and so on. (Most of the complexity is in destructured
bindings and default parameters, but it's not black magic, I promise.)
- Keep in mind it's possible to get a reference to an uninitialized
variable, even though it's not possible to access any value yet.

This mechanism already exists today, and `nameof` would just leverage
that mechanism. The static value would be computed *after* the
variable would have been linked (either at the global scope or after
the declaration exists), and only after falling back to the global
scope would the value fall back to a dynamic lookup and test.

-----

Isiah Meadows
cont...@isiahmeadows.com
www.isiahmeadows.com

On Sun, Jun 16, 2019 at 8:15 PM guest271314 <guest271...@gmail.com> wrote:
>
> > - If `y` is directly visible in scope and is neither a parameter or
> destructured binding, `nameof y` should just evaluate to `"y"`. This
> should be agnostic to whether the binding has been declared yet, so in
> your example, `x` should be set to `"y"`.
>
> The 1st question at 
> https://esdiscuss.org/topic/what-do-you-think-about-a-c-6-like-nameof-expression-for#content-33
>  remains:
>
> Without having composed or previously read the source code, at line 1 
> adjacent to ```nameof``` how does the user know that there will be later 
> declared variable named ```y```?
>
>
>
> On Sun, Jun 16, 2019 at 7:04 AM Isiah Meadows <isiahmead...@gmail.com> wrote:
>>
>> Here's my opinion:
>>
>> - If `y` is directly visible in scope and is neither a parameter or
>> destructured binding, `nameof y` should just evaluate to `"y"`. This
>> should be agnostic to whether the binding has been declared yet, so in
>> your example, `x` should be set to `"y"`.
>> - If `y` is entirely undeclared, it should be a runtime
>> `ReferenceError` in the same way it is when accessing undefined
>> globals. So in your second example, I'd expect it to throw before even
>> attempting assignment
>>
>> -----
>>
>> Isiah Meadows
>> cont...@isiahmeadows.com
>> www.isiahmeadows.com
>>
>> On Sun, Jun 16, 2019 at 12:00 AM guest271314 <guest271...@gmail.com> wrote:
>> >
>> > ```
>> > const x = nameof y
>> > const y = 1;
>> > ```
>> >
>> > At line 1 adjacent to ```nameof``` how does the user even know that there 
>> > is a variable that will be declared named ```y```?
>> >
>> > What is the output of ```x``` where there is no variable named ```y``` 
>> > later declared?
>> >
>> > ```
>> > const x = nameof y
>> > const z = 1;
>> > ```
>> >
>> > On Sun, Jun 16, 2019 at 12:03 AM Ron Buckton <ron.buck...@microsoft.com> 
>> > wrote:
>> >>
>> >> > What should occur where the code is
>> >>
>> >> It would be "y" in all 3 places.
>> >>
>> >> > ... is a proposal for _more_ than only getting the _name_ of an 
>> >> > _declared_ and _initialized_ variable?
>> >>
>> >> It is a proposal for getting the name of a _declared_ variable. Whether 
>> >> it is _initialized_ does not matter.
>> >>
>> >> > Should a ```RefefenceError``` _not_ be thrown simple because 
>> >> > ```nameof``` is used?
>> >>
>> >> No, an error is not thrown. ECMAScript is much more nuanced. Block scoped 
>> >> variables from 'let' or 'const' exist and can be *referenced* (via 
>> >> closure or export, currently) anywhere within the same block scope, even 
>> >> before they are initialized. Until they have been *initialized* (the line 
>> >> of code contain the declaration has been reached and evaluated), they 
>> >> exist in a "Temporal Dead Zone" (TDZ). Attempting to *dereference* them 
>> >> (i.e. access or store a value) while in this TDZ is what results in the 
>> >> ReferenceError.
>> >>
>> >> At no point does the `nameof` operator *dereference* the variable, so no 
>> >> error need be thrown.
>> >>
>> >> From: guest271314
>> >> Sent: Saturday, June 15, 4:29 PM
>> >> Subject: Re: Re: What do you think about a C# 6 like nameof() expression 
>> >> for
>> >> To: Ron Buckton
>> >> Cc: es-discuss@mozilla.org
>> >>
>> >>
>> >>
>> >>
>> >> What should occur where the code is
>> >>
>> >> ```
>> >> const x = nameof y
>> >> await new Promise(resolve => setTimeout(resolve, 100000)); // should x be 
>> >> "y" here?
>> >> await new Promise(resolve => setTimeout(resolve, 200000)); // should x be 
>> >> "y" here?
>> >> await Promise.all([new Promise(resolve => setTimeout(resolve, 300000)), 
>> >> ...doStuff()]); // should x be "y" here?
>> >> const y = 1;
>> >> ```
>> >>
>> >> ?
>> >>
>> >> The immediately invoked arrow function example (where a 
>> >> ```RefeferenceError``` is thrown) appears to demonstrate that to output 
>> >> the expected result of ```nameof``` within the context of the code example
>> >>
>> >> ```
>> >> const x = nameof y
>> >> const y = 1;
>> >> ```
>> >>
>> >> is a proposal for _more_ than only getting the _name_ of an _declared_ 
>> >> and _initialized_ variable?
>> >>
>> >> Should a ```RefefenceError``` _not_ be thrown simple because ```nameof``` 
>> >> is used?
>> >>
>> >> On Sat, Jun 15, 2019 at 11:16 PM Ron Buckton <ron.buck...@microsoft.com> 
>> >> wrote:
>> >>
>> >> ```
>> >> const x = nameof y
>> >> const y = 1;
>> >> ```
>> >>
>> >> `x` would have the value “y”. It would not matter if `y` were initialized 
>> >> or had yet been reached during execution. It does not deviate from the 
>> >> purpose of `let` or `const`, because you are not accessing the value of 
>> >> the identifier.
>> >>
>> >> Also consider that this is legal ECMAScript in a module:
>> >>
>> >> ```
>> >> export { y }
>> >> const y = 1;
>> >> ```
>> >>
>> >> The binding for `y` exists within the same block scope, it just has not 
>> >> yet been initialized. Exporting it via `export { y }`, closing over it 
>> >> via `() => y`, or accessing it via `nameof y` would all be the same. In 
>> >> all three cases you are accessing the *binding* of `y`, not the *value* 
>> >> of `y`. Even in the `() => y` case, you don’t access the *value* of `y` 
>> >> until you execute the function.
>> >>
>> >> From: guest271314 <guest271...@gmail.com>
>> >> Sent: Saturday, June 15, 2019 3:57 PM
>> >> To: Ron Buckton <ron.buck...@microsoft.com>
>> >> Cc: es-discuss@mozilla.org
>> >> Subject: Re: Re: What do you think about a C# 6 like nameof() expression 
>> >> for
>> >>
>> >> > Sorry, I meant to say “not entirely correct”.
>> >>
>> >> You have not yet confirmed if in fact the expected output is referencing 
>> >> a variable declared using ```const``` on the current line _before_ 
>> >> initialization _on the next line_.
>> >>
>> >> That example appears to deviate from the purpose and usage of 
>> >> ```const```, beyond the scope of ```nameof```, and if were implemented, a 
>> >> ```ReferenceError``` should _not_ be thrown when a ```const``` variable 
>> >> that has yet to be initialized _on the next line_ is referred to _on the 
>> >> current line_?
>> >>
>> >> Aside from that example, the code which essentially already implements 
>> >> ```nameof``` should be able to be found in the code which implements 
>> >> ```ReferenceError``` relevant to ```const```.
>> >>
>> >> On Sat, Jun 15, 2019 at 10:47 PM Ron Buckton <ron.buck...@microsoft.com> 
>> >> wrote:
>> >>
>> >> Sorry, I meant to say “not entirely correct”.
>> >>
>> >> From: Ron Buckton
>> >> Sent: Saturday, June 15, 2019 3:03 PM
>> >> To: guest271314 <guest271...@gmail.com>
>> >> Cc: es-discuss@mozilla.org
>> >> Subject: RE: Re: What do you think about a C# 6 like nameof() expression 
>> >> for
>> >>
>> >> > At that point in the example code the identifer ```y``` does not exist.
>> >>
>> >> That is not entirely incorrect. The identifier `y` exists, but its 
>> >> binding has not been initialized, otherwise you couldn’t refer to y in 
>> >> this case:
>> >>
>> >>
>> >>
>> >>
>> > _______________________________________________
>> > es-discuss mailing list
>> > es-discuss@mozilla.org
>> > https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to