tc39 / proposal-class-public-fields

Stage 2 proposal for public class fields in ECMAScript
https://tc39.github.io/proposal-class-public-fields/
488 stars 25 forks source link

Need userland reflection over class instance fields #11

Closed jeffmo closed 8 years ago

jeffmo commented 9 years ago

There needs to be a way to reflect over the defined instance fields of a class definition. This can likely take the form of something like Function.getOwnFieldDescriptor() and Function.defineField().

Additionally, in order to satisfy needs for some DOM interfaces (at least), there must be some way to lock down a class and prevent addition, removal, or mutation of it's fields. Something along the lines of Function.lockFields().

ljharb commented 9 years ago

Since fields only apply to something that's newable, does anything different need to happen if a function's [[Construct]] throws? Perhaps not, since that would just make the fields a no-op.

I'm assuming this reflective mechanism work across realms, since it's using internal slots - and that the mechanism would allow me to enumerate all of the fields on a function.

If I can define fields on a normal function, that's not a "class" - does that mean they would be initialized on new normalFunction() also?

jeffmo commented 8 years ago

Since fields only apply to something that's newable, does anything different need to happen if a function's [[Construct]] throws? Perhaps not, since that would just make the fields a no-op.

I'm not sure what you're getting at (with respect to fields being reflectable, at least)? Reflection would happen without actually executing or new-ing the class -- so there's no opportunity for [[Construct]] to throw during reflection.

I'm assuming this reflective mechanism work across realms, since it's using internal slots - and that the mechanism would allow me to enumerate all of the fields on a function.

Yes, both of these statements are correct.

If I can define fields on a normal function, that's not a "class" - does that mean they would be initialized on new normalFunction() also?

A good question. I can't think of a reason not to allow imperative fields to be defined on constructor functions...so by default I see no reason to prohibit it.

ljharb commented 8 years ago

I'm not sure what you're getting at

can I define fields on an arrow function? I'm thinking probably yes - they'd just never be instantiated?

jeffmo commented 8 years ago

I see. Yea, that might be a fair reason to try to limit this API to throw on non-classes then...

(It's always easier to lift the restriction later than it is to add it in)

ljharb commented 8 years ago

I suppose both the defining and reflecting methods would have to throw if [[FunctionKind]] isn't "classConstructor" - however, since there currently isn't any mechanism to expose the existence of this internal slot (thereby identifying "class" constructors), if the language adds something that throws when the slot is missing, i guarantee you i will be writing code that relies on the exception to brand-test for "class" functions :-) so if that's going to be added, we'd want a separate (not to be changed later) method that detects this internal slot value, otherwise it can't necessarily be changed later.

jeffmo commented 8 years ago

I'm going to leave this API out of the feature set for this proposal. I don't currently see any reason not to eventually add it, but it expands the scope of the proposal more than I think is necessary right now.