Why is "export default var a = 1;" invalid syntax?

Allen Wirfs-Brock allen at wirfs-brock.com
Mon Dec 15 23:20:11 PST 2014

On Dec 15, 2014, at 10:06 PM, Brendan Eich wrote:

> Ah, thanks -- I remember someone pointing this out, now that you mention it.
> My misunderstanding in the last two posts dings my ES6 quiz score! Who will get a perfect score in a fresh (uncoached) quiz setting? Is this telling us something? Anyway, I agree that `export default function a() {}` making an `a` binding is better, it resolves the confusing aspect in my misunderstood version of ES6 that Glen cited in his 7pm post.
> One more question below:
> Allen Wirfs-Brock wrote:
>>> This seems clear. As Dave said, he originally proposed an '=' in between 'default' and the *expression* to evaluate on the right. That design remembrance should make clear that the default export is a function expression (not function declaration) with 'a' the name only in the scope of that function (either for recursion or as a downward funarg).
>>> The 'default' binding won't be mutated via the final 'a = 2' statement, so the default-exported value is still the result of evaluating the function a(){} expression.
>> Not quite how it actually ended up.  See https://bugs.ecmascript.org/show_bug.cgi?id=2302 for background.
>> export default function ...
>> export default function  * ...
>> export default class ...
>> all act as declaration that create a module local binding (for the name in the declaration part)  that is initialized in the normal manner (hoisted for function/function*,  statement order initialization for class).  In addition that binding is exported using the reserved export name 'default'. Just like, an export of the same declaration without 'default', except such declaration use the same name for both the export name and the local binding name.
> So assigning `a = 2` won't affect the value of the default export, but will rebind `a`, given preceding `export default function a() {}` -- right?

It does both.  'a' is rebound to 2 and since the export name 'default' associates to 'a', any subsequent references in other modules tht are linked to the default export of this module will also see 2 because 'default' is really just the export name for 'a'.

>> For export default, if the declaration is anonymous (this required some minor syntax tweaking) , a local binding is still created (and initialized in the manner manner) but the local binding isn't locally referencable because it doesn't have a name that can be referenced via an IdentifierReference.
> Hmm, how's that work? Throwaway symbol name?
Well ultimately it's all linkages that at the implementation level hopefully resolve external (ie imported) references into direct references to exported variable binding.

At the spec. level, I just define a non-identifer name ("*default*") to the binding created by a anonymous 'export default'.  There can only be one per modules. It turns out all the declaration instantiation, binding lookup,  and module linking mechanism in the spec. work fine with such a name, so there is actually very few special cases in the spec. for such anonymous default exports. See https://people.mozilla.org/%7Ejorendorff/es6-draft.html#sec-exports-static-semantics-exportentries for how exports associate an export name with either a local binding name or an import name from some other module.

> I ask because Glen also wondered about the Module Record being reified in one of his posts. That's spec-internal, though (again, correction welcome).

Right, Module Record is just internal spec. mechanism used to define the module semantics.  It currently isn't reified.


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

More information about the es-discuss mailing list