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?

4 Answers 4

23

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.

Sign up to request clarification or add additional context in comments.

2 Comments

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."
@ANeves - Indeed! :-)
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)

Comments

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)

Comments

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)
    }
}

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.