Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
May 24, 2022 11:56 pm GMT

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

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 effectsfunction foo(callback) {  const val = callback();  if (val === true) {    // Do something if callback returns true  }}let bool = false;// badfoo(() => bool = true);// goodfoo(() => {  bool = true;});

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,  )));

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}. Its so long that we dont want it to take up space on the .map line!`));// good[1, 2, 3].map((number) => (  `A long string with the ${number}. Its so long that we dont 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;});

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

// badconst itemHeight = (item) => item.height <= 256 ? item.largeSize : item.smallSize;// badconst itemHeight = (item) => item.height >= 256 ? item.largeSize : item.smallSize;// goodconst itemHeight = (item) => (item.height <= 256 ? item.largeSize : item.smallSize);// goodconst itemHeight = (item) => {  const { height, largeSize, smallSize } = item;  return height <= 256 ? largeSize : smallSize;};

Enforce the location of arrow function bodies with implicit returns.

// bad(foo) =>  bar;(foo) =>  (bar);// good(foo) => bar;(foo) => (bar);(foo) => (   bar)

2. Classes & Constructors

Always use class. Avoid manipulating prototype directly.

// badfunction Queue(contents = []) {  this.queue = [...contents];}Queue.prototype.pop = function () {  const value = this.queue[0];  this.queue.splice(0, 1);  return value;};// goodclass Queue {  constructor(contents = []) {    this.queue = [...contents];  }  pop() {    const value = this.queue[0];    this.queue.splice(0, 1);    return value;  }}

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

// badconst inherits = require('inherits');function PeekableQueue(contents) {  Queue.apply(this, contents);}inherits(PeekableQueue, Queue);PeekableQueue.prototype.peek = function () {  return this.queue[0];};// goodclass PeekableQueue extends Queue {  peek() {    return this.queue[0];  }}

Methods can return this to help with method chaining.

// badJedi.prototype.jump = function () {  this.jumping = true;  return true;};Jedi.prototype.setHeight = function (height) {  this.height = height;};const luke = new Jedi();luke.jump(); // => trueluke.setHeight(20); // => undefined// goodclass Jedi {  jump() {    this.jumping = true;    return this;  }  setHeight(height) {    this.height = height;    return this;  }}const luke = new Jedi();luke.jump()  .setHeight(20);

Its 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()}`;  }}

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.

// badclass Jedi {  constructor() {}  getName() {    return this.name;  }}// badclass Rey extends Jedi {  constructor(...args) {    super(...args);  }}// goodclass Rey extends Jedi {  constructor(...args) {    super(...args);    this.name = 'Rey';  }}

Avoid duplicate class members.

// badclass Foo {  bar() { return 1; }  bar() { return 2; }}// goodclass Foo {  bar() { return 1; }}// goodclass Foo {  bar() { return 2; }}

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.

// badclass Foo {  bar() {    console.log('bar');  }}// good - this is usedclass Foo {  bar() {    console.log(this.bar);  }}// good - constructor is exemptclass Foo {  constructor() {    // ...  }}// good - static methods aren't expected to use thisclass Foo {  static bar() {    console.log('bar');  }}

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


Original Link: https://dev.to/stormytalent/50-hints-jses6-developer-must-know-4th-part-4ecl

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To