Best Practices for Long Constructors in JavaScript

I create objects with a lot of properties, and I wonder how to apply them. It seems nice to have really long constructors (creating new objects is not fun).

function Book(title, author, pages, chapters, publisher, datePublished, authorHometown, protagonistFavoriteColor) { this.title = title; this.authorpages = authorpages; this.pages = pages; this.chapters = chapters; this.publisher = publisher; this.datePublished = datePublished; this.authorHometown = authorHometown; this.protagonistFavoriteColor = protagonistFavoriteColor; } // not reliable to remember how to order params var rc = new Book("Robinson Crusoe", "Daniel Defoe", 342, 16, ...); 

I am wondering, maybe I should just set maybe three important properties in the constructor (e.g. title, author and pages) and write separate setters for the rest. Or should I use only setters for consistency? If configuring in this way is the best way to track, is there a good way in JS to mandate these methods to be called (like similar interfaces in Java)?

 function Book (title, author, pages){ this.title = title; this.author = author; this.pages = pages; this.chapters = null; this.publisher = null; this.datePublished = null; this.authorHometown = null; this.protagonistFavoriteColor = null; } var rc = new Book("Robinson Crusoe", "Daniel Defoe", 342); rc.setChapters(16); rc.setPublisher("John Smith Co."); rc.setDatePublished("04-25-1719"); rc.setAuthorHometown("London"); rc.setProtagonistFavoriteColor("lilac"); // we'd also want to mandate that these setters be called so nothing is left null 

Finally, would pass the object to the object of my constructor and destroy its complete defeat of the constructor pt?

+6
source share
4 answers

Best practice would be to pass an object defining the properties to the constructor:

 function Book(props) { // create variables out of object (if you need to) const { title, author, pages, chapters, publisher, datePublished, authorHometown, protagonistFavoriteColor } = props; // assign properties to instance object Object.assign(this, props); } const rc = new Book({ title: "Robinson Crusoe", author: "Daniel Defoe", pages: 342, chapters: 16, // rest of properties }); console.log(rc); 

JSFiddle Demo: https://jsfiddle.net/Lr6umykn/3/

+2
source

It seems that the best way is to use the arguments and mixin object. This is a kind of double-edged sword in which it makes code that makes reading an object easier, but the constructor itself is a little less obvious. eg.

 function Book(args) { Object.assign(this, args); } var rc = new Book({ name: "Robinson Crusoe", author: "Daniel Defoe", pages: 342 }); 

If you need default values, you can implement this with another mixin, for example.

 function Book(args) { args = Object.assign(args, { protagonistFavoriteColor: "Red" }); Object.assign(this, args); } 

Then a call, such as:

 var rc = new Book({ name: "Robinson Crusoe", author: "Daniel Defoe", pages: 342 }); 

Would give:

 rc.author; // "Daniel Defoe" rc.protagonistFavoriteColor // "Red" 

If you want to make sure that certain values ​​are provided, you will need to check at the end of the constructor that they are present and give an error.

+2
source

In es6, you can use destructuring and Object.assign to simplify the copy constructor template (a constructor containing an object with a parameter as the only argument):

 function Book({title, author, pages, chapters, publisher, datePublished, authorHometown, protagonistFavoriteColor}) { Object.assign(this, {title, author, pages, chapters, publisher, datePublished, authorHometown, protagonistFavoriteColor}); } var rc = new Book({title: "Robinson Crusoe", author: "Daniel Defoe", pages: 342, chapters: 16}); var copy = new Book(rc); console.log(JSON.stringify(rc)); console.log(JSON.stringify(copy)); console.log(copy == rc); // false 

He called it, because now you can conveniently create an object from another instance.

We list each property in Object.assign to assign only valid parameters.

Does this mean that the goal is to have a constructor in the first place? If that's all you do, then yes. Yes. But hopefully your class has some methods and goals besides this.

+2
source

I know this is an old query, but I wonder why no one mentioned complex objects. In my opinion, this is the easiest way to organize and store your data.

  1. create your constructor with ES6 destructuring:
 function Book({reference, publication, author}) { this.reference = reference; this.publication = publication; this.author = author; } 
  1. Implementation:
 var rc = new Book({ reference: { title: 'Robinson Crusoe', pages: 342, chapters: 16, protagonistFavoriteColor: 'lilac' }, publication: { publisher: 'John Smith co.', date: '04-25-1719' }, author: { name: 'Daniel Defoe', homeTown: 'London' } }); 
  1. Using:
 console.log(rc.reference.title); // 'Robinson Crusoe' console.log(rc.publication.date); // '04-25-1719' console.log(rc.author.name); // 'Daniel Defoe' 

This method also gives you the opportunity to access the entire category.

 console.log(rc.author); // {name: "Daniel Defoe", homeTown: "London"} console.log(rc.reference); // {title: "Robinson Crusoe", pages: 342, chapters: 16, protagonistFavoriteColor: "lilac"} 

When you are familiar with this organization, creating objects becomes simple and fun.

0
source

Source: https://habr.com/ru/post/1266827/


All Articles