Clarification on let/const

Allen Wirfs-Brock allen at wirfs-brock.com
Tue Jul 31 11:32:23 PDT 2012


On Jul 31, 2012, at 11:00 AM, Nicholas C. Zakas wrote:

> Hi,
> 
> I've been going through the spec trying to figure out a few edge cases for block bindings. It appears that there is not a functioning demo for these (Traceur is mostly working with var semantics, Firefox/Chrome are not at all spec-compliant), so just thought I would ask to get a better understanding of the expected behavior.
> 
> 1. If I'm interpreting this correctly, let and const declarations will throw an error if used with an identifier that is already defined within the same block. So I think that means this should throw an error:
> 
> function f() {
>     var count = 10;
>     let count = 20;   // error?
> }
> 

yes


> However, it seems like this would not (block variable shadowing function variable?):
> 
> function f() {
>     var count = 10;
> 
>     if (condition) {
>         let count = 20;   // no error?
>     }
> }
> 

yes, shadowing of outer declarations by block level declarations is permitted.



> And I would assume this is the same (using let instead of var):
> 
> function f() {
>     let count = 10;
> 
>     if (condition) {
>         let count = 20;   // no error?
>     }
> }
> Am I correct in my understanding of these?

yes

> 
> 2. Since ECMAScript 6 is always running in strict mode,

this is no longer the case.  ES6 has strict and non-strict modes just like ES5




> I'm assuming that attempting to assign to a declared constant would throw an error (in that it behaves similar to a non-writable property in strict mode)?
> 
> const MAX_ITEMS = 30;
> 
> MAX_ITEMS = 25;    // error?
> 
> Is that correct?

yes, and this is isn't intended to be tied to strict mode. Also I don't see how it relates to the cases you clarified above.

In the specification this is  supposed to be covered by 10.2.1.1.3 step 6, SetMutableBinding for a DeclarativeEnvironmentRecord.  However, I note that step 6 as currently written currently only throws in strict mode.  This is a carry over from the  ES5 spec. where it very rarely came into play.

The easy fix of this is to simply eliminate the strict mode test  in step 6.  But would introduce a minor semantic change from ES5:

In ES5, in the following code foo has an immutable binding within the body of the function:

(function foo() {foo = 42}

however, it only throws  if this is a strict mode function.  Otherwise, the assignment is just ignored.

If I simply make the spec. change to 10.2.1.1.3 step 6, it would be a breaking change to any non-strict  ES<6 code that actually did something like the above.  The specification would be simpler if we were willing to make that  breaking change, but it may be too risky.  One way or another the spec. will get fixed so that assignment to a const binding throws.

Allen


> 
> 
> Thanks,
> Nicholas
> -- 
> ___________________________
> Nicholas C. Zakas
> http://www.nczonline.net
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20120731/ab2a9d77/attachment.html>


More information about the es-discuss mailing list