Closed sylvainpolletvillard closed 5 years ago
@gibelium and I would like to engage in this proposal, but we are quite uncertain about what you mean with your second proposal point:
deep merge object models defaults at instanciation instead of using their prototypes
could you offer more explanation and maybe some psedo code examples of how v4 could feel different with the new proposals?
would you offer backward compatibility to 3.x or will full refactoring of defaults be needed?
Sure. In v3, we use prototypes to store defaults values:
M = Model({ x: Number }).defaults({ x: 42 })
is roughly equivalent to
M = data => Object.assign(Object.create({ x: 42 }), data)
so we can do this:
m = M({ x: 99 })
console.log(m.x) // 99
delete m.x;
console.log(m.x) // 42 (taken from prototype)
This is pretty cool but not a very common used feature. Actually, most JS developers don't even know how prototypal inheritance works.
Most users instead think of defaults as a one-time fill-in-the-gaps at object instanciation. Somethink like this:
M = data => Object.assign({ x: 42 }, data)
I personally think this is less elegant, but if it's easier to reason about and more useful to the users, I'm okay to switch to this behaviour for v4. This will be closer to the defaultTo
behaviour which is simply a default value assignement when constructor is called without args.
So this change will enable to merge defaults
and defaultTo
into a single method, huge win for simplicity. That also means this will be a breaking change and you'll need to change your code. This is why I keep this for v4
Update: I tried different syntaxes to pass a function for default values, but none was satisfying. So I decided that the library should take care of this for you, and dereference the default value at each model instanciation. This prevent users to explicitely set the default value to a common reference, but I can't think of any valid usecase for this.
The current plan is to remove ObjectModel defaults
method and replace it by defaultTo
without changes in the method signature.
Is there a way to set a default prototype? The following doesn't seem to work.
const {EventEmitter} = require('events')
const Crypto = ObjectModel({
name: String
}).defaultTo(EventEmitter.prototype)
I'm setting the prototype as follows but it would be nice to have a default.
Object.setPrototypeOf(
Crypto({
name: 'Tezos'
})
, EventEmitter.prototype
)
@RichAyotte lets discuss in a new issue: https://github.com/sylvainpolletvillard/ObjectModel/issues/104
Defaults assignments need a rework for v4.
What is needed ?
v3 issues
defaultTo
vsdefaults
is not clearProposed solutions
defaultTo
anddefaults
into a single method