stampit-org / stampit

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

Using destructuring assignment on initialize #309

Closed nachocab closed 7 years ago

nachocab commented 7 years ago

I thought this would behave like this:

Sentence = stampit({
  init(myArg, {myArg2 = 3}) {
    // ...
  }
})

Sentence(1) // myArg = 1, myArg2 = 3
Sentence(1, {myArg2: 5}) // myArg = 1, myArg2 = 5

but the second call doesn't re-assign myArg2 (it's still 3). Should I use a different syntax?

danielkcz commented 7 years ago

Unfortunately, you cannot use multiple arguments for stamps like this. I guess this can be seen as a disadvantage of stamps. It's recommended to wrap all arguments in a single object that is passed in a first argument. There is a good reason for that as when you are composing from various other stamps, you shouldn't make any assumption that there are more arguments available. It needs a kinda different mindset then you are probably used to from OO.

However, if you insist, it's possible to access other arguments like init(myArg, { args }) { ... } where args is an array of all arguments (including first one).

koresar commented 7 years ago

Hi, @nachocab @FredyC's answer is precise. Do you have any other questions?

Here, I rewrote your initializer to print the values as expected

Sentence = stampit({
  init(myArg, {args: [arg1, {myArg2} = {myArg2: 3}]}) {
    console.log(arg1, myArg2);
  }
})

Sentence(1) // myArg = 1, myArg2 = 3
Sentence(1, {myArg2: 5}) // myArg = 1, myArg2 = 5

Although, as @FredyC says, we do not recommend that pattern not only for stamps, but for any JavaScript in general. So, if I were you I'd write:

Sentence = stampit({
  init({myArg, myArg2 = 3}) {
    console.log(myArg, myArg2);
  }
})

Sentence({myArg: 1}) // myArg = 1, myArg2 = 3
Sentence({myArg: 1, myArg2: 5}) // myArg = 1, myArg2 = 5
nachocab commented 7 years ago

Got it, thank you both!