DEV Community

StormyTalent
StormyTalent

Posted on

50+ hints JS(ES6+) developer must know (4th part)

Hi, everybody.
Today we're going to have some tips about the arrow functions and classes.

1. Arrow function

When you must use an anonymous function (as when passing an inline callback), use arrow function notation.

// bad [1, 2, 3].map(function (x) { const y = x + 1; return x * y; }); // good [1, 2, 3].map((x) => { const y = x + 1; return x * y; }); 
Enter fullscreen mode Exit fullscreen mode

If the function body consists of a single statement returning an expression without side effects, omit the braces and use the implicit return. Otherwise, keep the braces and use a return statement.

// bad [1, 2, 3].map((number) => { const nextNumber = number + 1; `A string containing the ${nextNumber}.`; }); // good [1, 2, 3].map((number) => `A string containing the ${number + 1}.`); // good [1, 2, 3].map((number) => { const nextNumber = number + 1; return `A string containing the ${nextNumber}.`; }); // good [1, 2, 3].map((number, index) => ({ })); // No implicit return with side effects function foo(callback) { const val = callback(); if (val === true) { // Do something if callback returns true } } let bool = false; // bad foo(() => bool = true); // good foo(() => { bool = true; }); 
Enter fullscreen mode Exit fullscreen mode

In case the expression spans over multiple lines, wrap it in parentheses for better readability.

// bad ['get', 'post', 'put'].map((httpMethod) => Object.prototype.hasOwnProperty.call( httpMagicObjectWithAVeryLongName, httpMethod, ) ); // good ['get', 'post', 'put'].map((httpMethod) => ( Object.prototype.hasOwnProperty.call( httpMagicObjectWithAVeryLongName, httpMethod, ) )); 
Enter fullscreen mode Exit fullscreen mode

Always include parentheses around arguments for clarity and consistency.

// bad [1, 2, 3].map(x => x * x); // good [1, 2, 3].map((x) => x * x); // bad [1, 2, 3].map(number => ( `A long string with the ${number}. It’s so long that we don’t want it to take up space on the .map line!` )); // good [1, 2, 3].map((number) => ( `A long string with the ${number}. It’s so long that we don’t want it to take up space on the .map line!` )); // bad [1, 2, 3].map(x => { const y = x + 1; return x * y; }); // good [1, 2, 3].map((x) => { const y = x + 1; return x * y; }); 
Enter fullscreen mode Exit fullscreen mode

Avoid confusing arrow function syntax (=>) with comparison operators (<=, >=).

// bad const itemHeight = (item) => item.height <= 256 ? item.largeSize : item.smallSize; // bad const itemHeight = (item) => item.height >= 256 ? item.largeSize : item.smallSize; // good const itemHeight = (item) => (item.height <= 256 ? item.largeSize : item.smallSize); // good const itemHeight = (item) => { const { height, largeSize, smallSize } = item; return height <= 256 ? largeSize : smallSize; }; 
Enter fullscreen mode Exit fullscreen mode

Enforce the location of arrow function bodies with implicit returns.

// bad (foo) => bar; (foo) => (bar); // good (foo) => bar; (foo) => (bar); (foo) => ( bar ) 
Enter fullscreen mode Exit fullscreen mode

2. Classes & Constructors

Always use class. Avoid manipulating prototype directly.

// bad function Queue(contents = []) { this.queue = [...contents]; } Queue.prototype.pop = function () { const value = this.queue[0]; this.queue.splice(0, 1); return value; }; // good class Queue { constructor(contents = []) { this.queue = [...contents]; } pop() { const value = this.queue[0]; this.queue.splice(0, 1); return value; } } 
Enter fullscreen mode Exit fullscreen mode

Why? It is a built-in way to inherit prototype functionality without breaking instanceof.

// bad const inherits = require('inherits'); function PeekableQueue(contents) { Queue.apply(this, contents); } inherits(PeekableQueue, Queue); PeekableQueue.prototype.peek = function () { return this.queue[0]; }; // good class PeekableQueue extends Queue { peek() { return this.queue[0]; } } 
Enter fullscreen mode Exit fullscreen mode

Methods can return this to help with method chaining.

// bad Jedi.prototype.jump = function () { this.jumping = true; return true; }; Jedi.prototype.setHeight = function (height) { this.height = height; }; const luke = new Jedi(); luke.jump(); // => true luke.setHeight(20); // => undefined // good class Jedi { jump() { this.jumping = true; return this; } setHeight(height) { this.height = height; return this; } } const luke = new Jedi(); luke.jump() .setHeight(20); 
Enter fullscreen mode Exit fullscreen mode

It’s okay to write a custom toString() method, just make sure it works successfully and causes no side effects.

class Jedi { constructor(options = {}) { this.name = options.name || 'no name'; } getName() { return this.name; } toString() { return `Jedi - ${this.getName()}`; } } 
Enter fullscreen mode Exit fullscreen mode

Classes have a default constructor if one is not specified. An empty constructor function or one that just delegates to a parent class is unnecessary.

// bad class Jedi { constructor() {} getName() { return this.name; } } // bad class Rey extends Jedi { constructor(...args) { super(...args); } } // good class Rey extends Jedi { constructor(...args) { super(...args); this.name = 'Rey'; } } 
Enter fullscreen mode Exit fullscreen mode

Avoid duplicate class members.

// bad class Foo { bar() { return 1; } bar() { return 2; } } // good class Foo { bar() { return 1; } } // good class Foo { bar() { return 2; } } 
Enter fullscreen mode Exit fullscreen mode

Class methods should use this or be made into a static method unless an external library or framework requires using specific non-static methods. Being an instance method should indicate that it behaves differently based on properties of the receiver.

// bad class Foo { bar() { console.log('bar'); } } // good - this is used class Foo { bar() { console.log(this.bar); } } // good - constructor is exempt class Foo { constructor() { // ... } } // good - static methods aren't expected to use this class Foo { static bar() { console.log('bar'); } } 
Enter fullscreen mode Exit fullscreen mode

Thanks for your time and I hope this blog will be your assets during your development.

Top comments (0)