📜 ⬆️ ⬇️

Pure javascript. Objects and data structures. Asynchrony. Error processing

Translation of the book by Ryan McDermott clean-code-javascript

Table of contents:






Objects and data structures


Use getters and setters


In javascript, the keywords private and public are missing, which complicates the implementation of classes. It is better to use getters and setters to access the properties of an object than directly access them. You ask "Why?". Here are some reasons:


Poorly:
')
class BankAccount { constructor() { this.balance = 1000; } } const bankAccount = new BankAccount(); // , , ... bankAccount.balance -= 100; 

Good:

 class BankAccount { constructor(balance = 1000) { this._balance = balance; } // It doesn't have to be prefixed with `get` or `set` to be a getter/setter set balance(amount) { if (this.verifyIfAmountCanBeSetted(amount)) { this._balance = amount; } } get balance() { return this._balance; } verifyIfAmountCanBeSetted(val) { // ... } } const bankAccount = new BankAccount(); // , , ... bankAccount.balance -= shoesPrice; //   let balance = bankAccount.balance; 

Implement the private properties of your objects.


This is possible through closures.

Poorly:

 const Employee = function(name) { this.name = name; }; Employee.prototype.getName = function getName() { return this.name; }; const employee = new Employee('John Doe'); console.log(`Employee name: ${employee.getName()}`); // Employee name: John Doe delete employee.name; console.log(`Employee name: ${employee.getName()}`); // Employee name: undefined 

Good:

 const Employee = function (name) { this.getName = function getName() { return name; }; }; const employee = new Employee('John Doe'); console.log(`Employee name: ${employee.getName()}`); // Employee name: John Doe delete employee.name; console.log(`Employee name: ${employee.getName()}`); // Employee name: John Doe 


Asynchrony


Use promises instead of callbacks


Kolbeki lead to excessive nesting and poor readability of the code.

Poorly:

 const request = require('request'); const fs = require('fs'); const url = 'https://en.wikipedia.org/wiki/Robert_Cecil_Martin'; request.get(url, (requestErr, response) => { if (requestErr) { console.error(requestErr); } else { fs.writeFile('article.html', response.body, (writeErr) => { if (writeErr) { console.error(writeErr); } else { console.log('File written'); } }); } }); 

Good:

 const requestPromise = require('request-promise'); const fsPromise = require('fs-promise'); const url = 'https://en.wikipedia.org/wiki/Robert_Cecil_Martin'; requestPromise.get(url) .then((response) => { return fsPromise.writeFile('article.html', response); }) .then(() => { console.log('File written'); }) .catch((err) => { console.error(err); }); 

Async / Await makes code cleaner than promises


Promises are a very good alternative to callbacks, but in the ES2017 / ES8 specification, async / await has appeared, which offers an even better solution. All you need is to write a function with the async prefix, inside which you can write your asynchronous logic imperatively. Async / await can be used right now with the help of babel.

Poorly:

 const requestPromise = require('request-promise'); const fsPromise = require('fs-promise'); const url = 'https://en.wikipedia.org/wiki/Robert_Cecil_Martin'; requestPromise.get(url) .then((response) => { return fsPromise.writeFile('article.html', response); }) .then(() => { console.log('File written'); }) .catch((err) => { console.error(err); }); 

Good:

 const requestPromise = require('request-promise'); const fsPromise = require('fs-promise'); async function getCleanCodeArticle() { try { const url = 'https://en.wikipedia.org/wiki/Robert_Cecil_Martin'; const response = await requestPromise.get(url); await fsPromise.writeFile('article.html', response); console.log('File written'); } catch(err) { console.error(err); } } 


Error processing


Throwing mistakes is a good solution! This means that at runtime you will know if something went wrong. You can stop the execution of your application at the right time and see the location of the error using the stack of the trace in the console.

Do not ignore caught errors


Doing nothing with the caught error, you lose the opportunity to correct the error or to respond to it ever. The error output in the console (console.log (error)) does not give the best result, because the error can be lost among the displayed entries in the console. If you wrap a piece of code in try / catch, then you are assuming an error has occurred. In this case, you must have a backup plan.

Poorly:

 try { functionThatMightThrow(); } catch (error) { console.log(error); } 

Good:

 try { functionThatMightThrow(); } catch (error) { //    ( ,  console.log): console.error(error); //   -    : notifyUserOfError(error); //    -     : reportErrorToService(error); //     ! } 

Do not ignore errors in promises.


You should not ignore errors that occurred in the promis, for the same reason as trapped errors in try / catch.

Poorly:

 getdata() .then((data) => { functionThatMightThrow(data); }) .catch((error) => { console.log(error); }); 

Good:

 getdata() .then((data) => { functionThatMightThrow(data); }) .catch((error) => { //    ( ,  console.log): console.error(error); //   -    : notifyUserOfError(error); //    -     : reportErrorToService(error); //     ! }); 

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


All Articles