36

Is it possible to use destructuring assignment in a JavaScript class' constructor to assign the instance variables similar to how you can do it to normal variables?

The following example works:

var options = {one: 1, two: 2};
var {one, two} = options;
console.log(one) //=> 1
console.log(two) //=> 2

But I cannot get something like the following to work:

class Foo {
  constructor(options) {
    {this.one, this.two} = options;
    // This doesn't parse correctly and wrapping in parentheses doesn't help
  }
}

var foo = new Foo({one: 1, two: 2});
console.log(foo.one) //=> I want this to output 1
console.log(foo.two) //=> I want this to output 2
4
  • 2
    I think the more general question is whether there's a destructuring assignment form that provides for creating properties on an existing object instead of an object initializer. Commented Jun 30, 2016 at 15:29
  • 1
    Anyway there's always Object.assign(this, options); Commented Jun 30, 2016 at 15:29
  • 1
    It's worth mentioning that you can apply the same syntax outside of constructors as well. Given are two objects: let o = {a: 1, b: 2}, p = {};. Deconstruct o to a less complex p is a peace of cake: ({b: p.b} = o); yields Object {b: 2} for p. Commented Jun 30, 2016 at 16:23
  • Does this answer your question? object destructuring without var Commented Jan 18, 2021 at 1:04

2 Answers 2

70

There are multiple ways of doing this. The first one uses destructuring only and assigns the properties of options to properties on this:

class Foo {
  constructor(options) {
    ({one: this.one, two: this.two} = options);
    // Do something else with the other options here
  }
}

The extra parentheses are needed, otherwise the JS engine might mistake the { ... } for an object literal or a block statement.

The second one uses Object.assign and destructuring:

class Foo {
  constructor(options) {
    const {one, two} = options;
    Object.assign(this, {one, two});
    // Do something else with the other options here
  }
}

If you want to apply all your options to the instance, you could use Object.assign without destructuring:

class Foo {
  constructor(options) {
    Object.assign(this, options);
  }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks @nils! This is exactly what I was looking for. The first solution is the most concise and uses a slightly more advanced destructuring that you'd either already know about or quickly figure out when reading/running the code. The 2nd is the clearest and most obvious while the 3rd is great for the use case you outlined.
3

In addition to Nils´s answer. It also works with object spread (...)

class Foo {

  constructor(options = {}) {
    ({
      one: this.one,
      two: this.two,
      ...this.rest
    } = options);
  }
}

let foo = new Foo({one: 1,two: 2,three: 3,four: 4});

console.log(foo.one);  // 1
console.log(foo.two);  // 2
console.log(foo.rest); // {three: 3, four: 4}

... and/or custom settters for further processing

class Foo {

    constructor(options = {}) {
        ({
            one: this.one,
            two: this.two,
            ...this.rest
        } = options);
    }
   
    set rest(options = {}) {
        ({
          three: this.three,
          ...this.more
        } = options);
    }
}

let foo = new Foo({one: 1,two: 2,three: 3,four: 4});

console.log(foo.one);   // 1
console.log(foo.two);   // 2
console.log(foo.three); // 3
console.log(foo.more);  // {four: 4}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.