-
Notifications
You must be signed in to change notification settings - Fork 25
Evaluation order for static properties vs class declaration #40
Comments
class User {
static schema = {lol: User} // User is undedined (is a bug)
} It seems to me improper specification and should not follow it. And I think that in this way many believe. but where to go. I have to write a decorator such as: @schema({
foo: User
})
class User {} but this not works works just ugly way class User {}
User.schema = {lol: User} But what if I want to create a class in expression? return (function(){
class User {}
User.schema = {lol: User}
return User
})() It is obvious that this is a bug, and the specification is not true |
Copying the following from the referenced issue for posterity: The class properties spec states (Step 24.ii.a) that the initializer scope inherits from the class-body scope; And the ES6 spec states (Step 4) that the class body scope does have access to the class binding (no TDZ). So indeed, the code above should work as expected. I am planning to write out proper spec text for the next TC39 meeting at the end of July, so hopefully this will reduce confusion around some of these things. |
Oh, and you're right in pointing out that 24.v.c.a is flawed! Things have changed a bit such that static class property initializers don't actually evaluate until the end of the class definition evaluation process -- so the spec text over in the README is a little outdated there. That's my fault, apologies! |
@jeffmo I think you may be misunderstanding what Step 4 does. That creates the binding in the class body scope, absolutely, but it does not give it a value, it leaves it uninitialized. The value of the class constructor
is the one that initializes the binding, and currently in the spec text that happens after the static values are evaluated. That line would have to be moved to be above the static property evaluation for it to be able to access the class name binding. |
You're right and this is why I followed up with the clarification that we've moved the step described in 24.v.c.a to the end of the procedure (i.e. after Step 23 that you're pointing out). Apologies for taking for granted that you knew about that tweak to the proposal. |
Okie doke, cool. I couldn't quite tell from the post above, my bad. |
An edge case came to mind that I don't think the decorator spec specifies well, but I'm curious for your thoughts. Given a case like this:
Ignoring the class property for a second, the decorator spec doesn't make it clear if If the expectation is that The other tough part there being that the current spec defines the internal class-name binding to be This is all moot if the decorator return value doesn't update the class body binding, but that has its own edge cases for users. |
I think @wycats has some solutions for this scenario. He'd included general thoughts in the previous TC39 meeting, so I'll defer to him here for details |
Raised over in loganfsmyth/babel-plugin-transform-decorators-legacy#17 but I figured I'd file a proper bug to get a solid answer. What is the expected behavior of
with the current spec, it looks like this would be a TDZ error because the
Foo
property assignment would be evaluated as step24.v.c.a
ofClassDefinitionEvaluation
, and theFoo
binding does not get initialized until step26.i
.Babel 6's class property implementation currently evaluates
me = Foo
afterFoo
has been initialized, but mytransform-decorators-legacy
plugin will result inFoo
being uninitialized at this point, and the difference between the two can cause trouble for users since code like this will work with standard Babel 6 until they enable decorators, at which point it will break.The text was updated successfully, but these errors were encountered: