How to spread an object into a classes properties in JavaScript
Asked Answered
P

4

17

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?

Perspiratory answered 18/9, 2017 at 6:55 Comment(0)
S
20

If you're using Object.assign, you don't use spread notation; just remove the ... (and optionally remove the if):

class Person {
    constructor (obj) {
        this.first = "";
        this.last = "";
        this.age = ""; // Consider a number rather than ""?

        // (No need for the `if`)
        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);
.as-console-wrapper {
    max-height: 100% !important;
}

Note that you don't need the if, because Object.assign ignores null or undefined sources.

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

Not in this example, where you're doing it in the constructor and so the object already exists. There is property spread notation, but it's in object initializers (object literals), so doesn't apply to putting objects in an existing object. That's what Object.assign is for.

Shiv answered 18/9, 2017 at 6:58 Comment(2)
We also don't need the if (obj) { … }, because Object.assign handles null and undefined. MDN quote: "Note: Object.assign() does not throw on null or undefined sources."Adur
@Adur - Indeed! :-)Shiv
R
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)
Riff answered 18/9, 2017 at 7:11 Comment(0)
R
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)
Rambort answered 18/9, 2017 at 6:58 Comment(0)
F
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)
    }
}
Familial answered 21/10, 2021 at 10:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.