in #272, I made a point about the nature of a class that is being lost in this proposal, namely, the breaking of the guarantees about the relationship between base classes and derived classes. Here, I offer a solution that can be implemented without sacrificing the intent of any decision made by TC39.
Put data members on the prototype. This part is non-negotiable. Without this, the guarantees are broken. However, this is not the whole of the solution. With this alone, some of the intent of the proposal decisions get lost.
Wrap all initializer values as functions. Basically, keep doing what you're doing now.
Associate any non-function object on the prototype with its initializer. This is where it starts getting good.
Create a Reflect.setInitializer(target, prop, fn). This function should essentially replace the property value as well as the initializer that goes with it. This gives us the missing ability to change our "field" values at leisure.
Use Set semantics in the initializers. This isn't a foul. The data members were already defined onto the prototype. So define semantics have been upheld.
Nothing else to change. The proposal will still run all the initializers on a per-instance basis, essentially copying the prototype onto the instance. Done like this, the gotchas associated with public fields will be no more. Not to mention, you gain the ability to edit the values of a class' fields as you would when replacing a prototype function.
in #272, I made a point about the nature of a class that is being lost in this proposal, namely, the breaking of the guarantees about the relationship between base classes and derived classes. Here, I offer a solution that can be implemented without sacrificing the intent of any decision made by TC39.
Put data members on the prototype. This part is non-negotiable. Without this, the guarantees are broken. However, this is not the whole of the solution. With this alone, some of the intent of the proposal decisions get lost.
Wrap all initializer values as functions. Basically, keep doing what you're doing now.
Associate any non-function object on the prototype with its initializer. This is where it starts getting good.
Create a
Reflect.setInitializer(target, prop, fn)
. This function should essentially replace the property value as well as the initializer that goes with it. This gives us the missing ability to change our "field" values at leisure.Use Set semantics in the initializers. This isn't a foul. The data members were already defined onto the prototype. So define semantics have been upheld.
Nothing else to change. The proposal will still run all the initializers on a per-instance basis, essentially copying the prototype onto the instance. Done like this, the gotchas associated with public fields will be no more. Not to mention, you gain the ability to edit the values of a class' fields as you would when replacing a prototype function.
If you want to see this concept in action, try taking a look at: https://github.com/rdking/ClassicJS
The main difference is that you won't be creating multi-level instance objects.