16

Basically here's what I'm trying to accomplish.

class Person {
  constructor (obj) {
    this.first = ''
    this.last = ''
    this.age = ''

    if (obj) {
      Object.assign(this, ...obj)
    }
  }
}

const a = new Person()
console.log('Not spreading: ', a)

const b = new Person({ first: 'Alex', last: 'Cory', age: 27 })
console.log('Spreading: ', b)

Is there a way to spread an object like this to populate a class?

Alex Cory
  • 10,635
  • 10
  • 52
  • 62

4 Answers4

20

If you're using Object.assign, you don't use spread notation; just remove the ...:

class Person {
  constructor (obj) {
    this.first = ''
    this.last = ''
    this.age = ''

    if (obj) {
      Object.assign(this, obj)     // <============ No ...
    }
  }
}

const a = new Person()
console.log('Not spreading: ', a)

const b = new Person({ first: 'Alex', last: 'Cory', age: 27 })
console.log('Spreading: ', b)

There is a proposal (currently at Stage 3, so likely to be in ES2018, and widely supported by transpilers) that does object property spread in object initializers, but that wouldn't apply to your situation where the object already exists.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
8

You could use deconstruction and take only the properties, you need.

class Person {
    constructor ({ first = '', last = '', age = '' } = {}) {
        Object.assign(this, { first, last, age });
    }
}

const a = new Person()
console.log('Not spreading: ', a)

const b = new Person({ first: 'Alex', last: 'Cory', age: 27, foo: 42 })
console.log('Spreading: ', b)
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
2

Is this what you're looking for?

class Person {
  constructor (obj) {
    this.firstName = ''
    this.lastName = ''
    this.age = ''
    if (obj) {
      Object.assign(this, obj)
    }
  }
}

const a = new Person()
console.log('Not spreading: ', a)

const b = new Person({ firstName: 'Alex', lastName: 'Cory', age: 27 })
console.log('Spreading: ', b)
JSON Derulo
  • 9,780
  • 7
  • 39
  • 56
0

I would personally prefer to use a seperate method as it is not possible to have multiple constructors in JS. In the following example I create new objects using a static fromObject() method which returns a new object. Therefore you can keep your normal constructor and create new objects using spread syntax as well.

Note: I am using typescript here.

export class Point {
    readonly x: number
    readonly y: number

    constructor(x: number, y: number) {
        this.x = x;
        this.y = y;
    }

    static fromObject({x, y}: {x: number, y: number}) {
        return new Point(x, y)
    }
}
mleister
  • 1,697
  • 2
  • 20
  • 46