3

I've recently seen this code:

class Foo {
  constructor({
    a,
    b,
    c = []
  }) {
    this.a = a;
    this.b = b;
    this.c = c;
    console.log(this);
  }
}
const foo = new Foo({
  a: 1,
  b: 2
});

But I've never seen parameters defined with curly braces wrapping the parameter names. My linter complains about it, but the code works fine and so I assume that it is valid as it executes without error.

I've read the MDN docs about, class, constructor and default arguments. However, I do not see this pattern described anywhere (maybe I missed it?).

What is it I'm looking for, does this pattern have a name, or is it described somewhere?

Xotic750
  • 22,914
  • 8
  • 57
  • 79
  • 1
    @Downvoter, in what way could this question be improved? – Bathsheba Sep 23 '16 at 12:58
  • Yes, I will improve it if I know what needs improving. – Xotic750 Sep 23 '16 at 13:00
  • 1
    It is "parameter destructuring". –  Sep 23 '16 at 13:05
  • 1
    Not the downvoter, but the question could have been improved by not being asked. I know it's a little hard to Google for this kind of thing, but "stack overflow curly brackets in function parameter list" worked for me. Also, if you consider yourself a semi-professional JS developer, I really recommend going through a list of all the new ES6 features, of which there are several, such as [this one](http://es6-features.org/#ParameterContextMatching). –  Sep 23 '16 at 13:11
  • I tried several searches and just couldn't find it. It seemed reasonable to ask what it was that I was looking at via example. Thanks. Perhaps I should delete the question? – Xotic750 Sep 23 '16 at 13:13
  • @torazaburo Javascript is something that I do for a little fun in my spare time. I'm not a programmer. Usually I can find and read everything new. It was just one of those times that I was falling flat on my face at every turn. – Xotic750 Sep 23 '16 at 13:18

2 Answers2

4

It is parameter destructuring.

However, in this case, you could simply do

class Foo {
  constructor(opts) {
    Object.assign(this, {c: []}, opts);
    console.log(this);
  }
}

const foo = new Foo({
  a: 1,
  b: 2
});

You should find some kind of "es6" flag for your linter to make it happy.

  • Thanks. I was guessing that it was similar, but didn't know what it was called. I guess that I need to update my linter as I already have the flag set. – Xotic750 Sep 23 '16 at 13:16
  • 1
    `Object.assign` is the way to go here. A little shorter if you put the `c` in an object in the same call `Object.assign(this, {c: []}, opts);`, though likely at the cost of an extra allocation. –  Sep 23 '16 at 13:35
  • I wonder if this has any impact on optimizations. Some engines have optimizations available when they're able to statically determine all the properties the object will have. It's possible that they could try to figure it out from the call site(s). –  Sep 23 '16 at 13:39
2

But I've never seen arguments defined like this before.

That's destructuring, just used on the arguments.

I couldn't find a good reference, but I believe thats an ES6 feature. What it does is decompose an object argument into individual variables and assigning the values of the properties with the same name to the variables.

It's similar to doing:

class Foo {
  constructor(obj) {
    this.a = obj.a;
    this.b = obj.b;
    this.c = obj.c || [];
    console.log(this);
  }
}
Joseph
  • 117,725
  • 30
  • 181
  • 234