Thanks for your help Rick! I've corrected a few, but wasn't sure about some 
others. Let me know if I'm missing something in the following:

From: Rick Waldron [mailto:[email protected]] 
Sent: Sunday, October 21, 2012 17:07

> nit: The comment itself says "// error! used a `let` before declaration.", 
> might be nice to highlight that the error will occur until the let is 
> assigned, ie. I can initialize it, but reads will throw until it's assigned.

If I'm understanding you correctly, you're saying that this should throw?

let x;
assert(x === undefined); // error! Use of `x` before it is assigned.

I was under the impression the temporal dead zone was about 
use-before-definition, not use-before-assignment. (For const they are the same, 
since the "Static Semantics: Early Errors" note on page 125 of the spec gives a 
Syntax Error if the Initialiser is omitted from the LexicalBinding.) That is:

"A let and const declarations define variables that are scoped to the running 
execution context’s LexicalEnvironment. The variables are created when their 
containing Lexical Environment is instantiated but may not be accessed in any 
way until the variable’s LexicalBinding is evaluated. A variable defined by a 
LexicalBinding with an Initialiser is assigned the value of its Initialiser’s 
AssignmentExpression when the LexicalBinding is evaluated, not when the 
variable is created. If a LexicalBinding in a let declaration does not have an 
an Initialiser the variable is assigned the value undefined when the 
LexicalBinding is evaluated."

This implies to me that the first line above evaluates the LexicalBinding, 
assigning the variable the value undefined; since the LexicalBinding is 
evaluated, the "may not be accessed" clause no longer applies, and no error 
should occur.


> Not sure of the number, but there is a slide titled "Block Scoping" with this:

> if (Math.random() > 0.5) {
>  function go() {
>    console.log("gone!");
>  }
>  ...
> }
> assert(typeof go === "undefined");

> I'm not sure I get what this one is trying to illustrate, because "go" will 
> always be initialized, regardless of the condition

I believe this is not true. The current semantics for block-scoped functions 
bind them to the block, not to the surrounding function. (That is, a 
FunctionDeclaration creates an entry into LexicallyDeclaredNames, not into 
VarDeclaredNames.)

Even in ES5, this behavior is unspecified: see the "NOTE" under the "Semantics" 
heading under section 12 of ES5.1, where it notes that even though Statement 
does not include FunctionDeclaration, implementations often allow it, with 
"significant and irreconcilable variations." (So, I don't think "go" will 
always be initialized in all browsers. For example, in IE10 strict mode the 
above code is a SyntaxError.) It also says that "Future editions of ECMAScript 
may define alternative portable means for declaring functions in a Statement 
context."

And indeed, in ES6 the Declaration grammar production is introduced as a 
sibling to Statement under Block. It includes LexicalDeclaration and 
FunctionDeclaration; VariableStatements are left under Statement. And the Block 
Declaration Instantiation algorithm (10.5.4) includes both LexicalDeclarations 
and FunctionDeclarations, i.e. FunctionDeclarations are added to the block's 
Declarative Environment Record instead of to the environment record of the 
containing function.

 
> new Set(...document.body.children);

> is a Syntax Error, use: 

> new Set([ ...document.body.children ]);

> Same for: 
> new Set(...array)
> Math.max(...array);
> Math.max(0, ...array, 5, ...array2);
> new Date(...dateFields);
> array.push(...array2);

I don't think any of these is a syntax error, since spread works for function 
calls/constructs too. See http://tc39wiki.calculist.org/es6/spread/ or section 
11.2.5 of the draft spec wherein the expanded runtime semantics for 
ArgumentListEvaluation are given (in particular ArgumentList: 
...AssignmentExpression and ArgumentList: ArgumentList, 
...AssignmentExpression). However, you are right that the sets should be 
constructed that way, since the Set constructor accepts an iterable and not 
varargs. Much appreciated!

Also, I just realized that in rearranging my slides I used spread before 
discussing it -_-. Will need to fix. Maybe "rest and spread" are more comfort 
than cowpath-paving...

> Weak Sets aren't specified yet. Might be wise to omit that?

Yeah, probably a good place to trim the fat. They are harmonious though, right? 
Since they're necessary for revocable proxies.

> One of WeakMap's best use cases is private data...

> ... This way any number of methods, both on C's prototype or class-side 
> functions, as long as they are defined in the same scope that "priv" is bound 
> to, can access the private cache in "priv". This beats leaky plain object 
> abstractions for a serious win :)

The problem I've always had with this is that using weak maps for objects you 
control is silly, when you could just use symbols. Indeed I illustrate the 
symbol vs. weak map question in my "Symbols Again" slide. Weak maps are more 
correct for objects you don't control though, due to the possibility of 
extension-prevented objects (as I plan to point out when that slide comes up). 
But for the simple private data use case, symbols are great. I was really glad 
Brendan reminded me that the values are also held weakly, since otherwise weak 
maps just reduce to a more-cumbersome, but safer, version of symbols.

Again, thanks for your help, and see you tomorrow!

_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to