0

Is there a shorthand way to add properties to an instance of a class in javascript?

Edit: The duplicate answers are about adding properties to an object not a class. I'm trying to make it easy for the user to add about 10-20 properties. I'm also trying to make sure they can't add their own properties but can only add values to the predefined properties. I don't know how to do that.

I have a javascript "class":

function Car(){
this.make="";
this.model="";
//...
}

To create an instance and add properties I would use:

var mycar = new Car();
    mycar.make="honda";
    mycar.model="civic";
    //...

Is there a shorthand way to create an instance and add the properties so I don't have to type "mycar." each time?

techdog
  • 1,451
  • 3
  • 19
  • 38
  • 2
    Pass them in the _constructor_, ie `function Car(make, model) {... }` – Phil Feb 07 '18 at 22:17
  • Possible duplicate of [How can I add a key/value pair to a JavaScript object?](https://stackoverflow.com/questions/1168807/how-can-i-add-a-key-value-pair-to-a-javascript-object) – Heretic Monkey Feb 07 '18 at 22:20

3 Answers3

5

If your constructor doesn't do anything important, you can use Object.create():

function Car() {
  //...
}

console.log(
  Object.create(
    Car.prototype,
    Object.getOwnPropertyDescriptors(
      { make: 'honda', model: 'civic' }
    )
  )
);

I wouldn't exactly call this "shorthand", but it is a single statement, and it omits invoking Car() if your constructor's body is redundant.

I'd personally recommend using Object.assign() within the body of your constructor:

function Car(props) {
  /* to formally mimic behavior of default parameters specification */
  // props = arguments.length < 1 || props === undefined ? {} : props;
  /* commonly used "good-enough" ES5 equivalent */
  props = props || {};
  Object.assign(this, props);
}

console.log(
  new Car({ make: 'honda', model: 'civic' })
);

Or ES6:

class Car {
  constructor (props = {}) {
    Object.assign(this, props);
  }
}

console.log(
  new Car({ make: 'honda', model: 'civic' })
);
Patrick Roberts
  • 49,224
  • 10
  • 102
  • 153
  • Why complicate things when you can just pass them in as arguments like the constructor pattern is used for? – Andrew Li Feb 07 '18 at 22:27
  • 1
    @Li357 I tried to make it clear that wasn't my main recommendation, I was just pointing out it was possible to create an instance of `Car` without explicitly invoking the constructor. If you want I can try to make it more clear that my last two approaches are my actual recommendation. – Patrick Roberts Feb 07 '18 at 22:29
  • I was just wondering, since OP has shown that their constructor sets two instance variables, then resets them immediately, that you can just pass them as separate arguments as opposed to an object with keys. – Andrew Li Feb 07 '18 at 22:30
  • If you have only two keys, that is fine, but what if your class has several properties? Surely you don't want to assign each one at a time. – Patrick Roberts Feb 07 '18 at 22:31
  • I agree, but in this case OP shows only two properties. Nevermind me then. – Andrew Li Feb 07 '18 at 22:34
  • 2
    I think the third example would be easy for a user to type in 10-20 properties without getting confused. It looks like though the user can assign any properties they want. If they make a spelling mistake it would add the property. How do I preset them so that only the properties I specify can be added? – techdog Feb 07 '18 at 22:48
1

You should use the constructor's parameters:

function Car(make, model) {
  this.make = make;
  this.model = model;
}
var mycar = new Car("honda", "civic");
trincot
  • 317,000
  • 35
  • 244
  • 286
-1

You can use Object.assign function.

function Car() {
  this.make = "";
  this.model = "";
}

var mycar = new Car();
Object.assign(mycar, { make: "honda", model: "civic" });

console.log(mycar);
Ele
  • 33,468
  • 7
  • 37
  • 75
  • This has been asked and answered many times. I notice your name coming up a lot as I vote to close duplicates. Are you checking for duplicates before answering? – Heretic Monkey Feb 07 '18 at 22:20
  • A) This is more code bytes-wise and B) this makes no sense! Why would you set them to empty strings then change them if you could *use the constructor pattern correctly and pass them in as arguments*?? – Andrew Li Feb 07 '18 at 22:26
  • @Li357 My answer *provides a shorthand way*. – Ele Feb 07 '18 at 22:29
  • @Ele How is this shorter then passing the values into the constructor? That would be better practice, more readable and shorter opposed to using Object.assign – Andrew Li Feb 07 '18 at 22:31
  • @Li357 I agree, however, I'm using the approach from the OP. Nobody has information about the context of his/her code. Nobody knows why he/she has written the constructor with empty values for initialization. Further, with this approach, the OP will know another way to assign properties to objects. – Ele Feb 07 '18 at 22:34
  • @Ele IMO the fact they explicitly show their constructor with the same properties as the ones they assign to lines later gives enough context. – Andrew Li Feb 07 '18 at 22:38