DEV Community

Cover image for JS Constructor Params vs This: Which Do You Use?
Mike Cronin
Mike Cronin

Posted on

JS Constructor Params vs This: Which Do You Use?

I still never quite know what to do with JS constructor parameters and functions used in the constructor. I'll explain what I do and my logic behind my reasoning, but I'd like to hear what you all do in the comments. I haven't had much luck really Googling this particular topic so I hope this sheds some light on the subject.

This vs Parameters

Take the example below, would you do it like this:

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
    this.bio = this.setBio();
  }

  setBio() { 
    // pretend this is more complicated 
    return `Name: ${this.name}, Age: {this.age}`;
  }

  doThing() {
    // some server call that uses name and age 
  }
}
Enter fullscreen mode Exit fullscreen mode

Or, would you do:

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
    this.bio = this.setBio(name, age);
  }

  setBio(name, age) { 
    // again, assume this was complex
    return `Name: ${name}, Age: {age}`;
  }
}
Enter fullscreen mode Exit fullscreen mode

So, that's an extremely contrived example, but I think you get the idea. When dealing with constructor helper functions, do you pass in arguments, or just use this? Personally, my little rule is:

any function using properties inside the constructor uses the constructor parameters, not class properties

And the reason for that is that this technically breaks:

class Person {
  constructor(name, age) {
    this.bio = this.setBio();
    this.name = name;
    this.age = age;
  }

  setBio() { 
    // pretend this is more complicated 
    return `Name: ${this.name}, Age: {this.age}`;
  }
}
Enter fullscreen mode Exit fullscreen mode

Since we're using class properties, you can't tell from line 3 that setBio has to be run after name and age have been set (again, pretend this is a more complicated function). However, using the parameters directly would prevent the order from mattering.

Generated on Generated

Then you can also have situations that require generated properties to exist.

class Person {
  constructor(name, age) {

    this.name = name;
    this.age = age;
    this.bio = this.setBio(name, age);

    sendEmail(this.bio)
  }

  setBio(name, age) { 
    // pretend this is more complicated 
    return `Name: ${this.name}, Age: {this.age}`;
  }

  sendEmail(bio) { 
    // some AWS ping to send an email
  }
}
Enter fullscreen mode Exit fullscreen mode

Again, SUPER simple example, pretend that bio was actually worth a helper function to generate. But what do you do in that situation? I feel silly passing in a this property to a function, but if I don't I run into the same issues as before, that it's not clear that sendEmail can only be run after setBio is generated. And yes, comments or something could clear this up, but I would prefer programmatically safe code.

What are your thoughts?

So that's what I do, what have you come up with? And yes, I know that functional, non-class setups could side step this issue altogether. But I'm specifically looking for your take on class based decisions. Let me know what you think below and as always, happy coding everyone.

Top comments (0)