stampit-org / stampit

OOP is better with stamps: Composable object factories.
https://stampit.js.org
MIT License
3.02k stars 102 forks source link

Compose using an instance? #336

Closed astanciu closed 6 years ago

astanciu commented 6 years ago

I can't figure out if this is possible and if so, how.

I'd like to be able to compose using an existing POJO or previous instance. ex:

const obj = {name: 'something'}

const Thing = stampit.compose(obj, OtherStamp, etc..)

I saw there's a convert-class utility, why not a convert-object? or is there a simpler way to do this other than merging object myself?

koresar commented 6 years ago

Sure there is a way. Actually, three ways. :)

If your POJO props need to go the __proto__ then:

const obj = {name: 'something'}
const Thing = stampit.methods(obj).compose(OtherStamp, etc..)

If they need to be regular properties (a-la mixin) then:

const obj = {name: 'something'}
const Thing = stampit.props(obj).compose(OtherStamp, etc..)

If you want some control over assignment logic then:

const obj = {name: 'something'}
const Thing = stampit.init(function () {
  this.name = obj.name;
}).compose(OtherStamp, etc..)

A good idea would be to extract that stamp to a separate variable, which would have a descriptive name. For example:

const HaveNameSomething = stampit.props({name: 'something'})

const Thing = stampit(HaveNameSomething, OtherStamp, etc..)

Here is a 5 min article which can help you to get your head around the above code.

astanciu commented 6 years ago

Amazing, so simple.. thank you.

astanciu commented 6 years ago

Quick followup, if obj was instantiated from a Stamp, its methods are on proto, which means neither .props nor .methods will pick them up:

  const Bar = stampit.methods({
    bar() {
      console.log('bar');
    }
  });

  const obj = Bar();

  const a = stampit.props(obj)(); // a.bar() undefined
  const b = stampit.methods(obj)(); // b.bar() undefined
  const c = stampit.methods(obj.__proto__)(); // bcbar() exists

Is this recommended if you want to enhance an existing Instance: const d = stampit.props(obj).methods(obj.__proto__).compose(Something)()

koresar commented 6 years ago

We recommend developers to do whatever they want with they code! Stampit do not have any formal rules you should follow. So, yeah. Your code is absolutely valid and recommended. :)

Good job on reading the above mentioned article. 👍