
Guide for the daily JavaScripter
This document is a summary of good programming practices in js in general.
Part of the document is based in Airbnb guideline, and other in profesional experience.
https://github.com/airbnb/javascript
TheNODE.JS section is a summary of different readings and my own experience in the tecnology.
Content list
- Paradigm
- Naming conventions
- Semicolons
- Comments
- Error handling
- Promise
- Comparision
- Iterations
- Functions
- String
- Destructuring
- Arrays
- Objects
- Properties
- Modules
- Primitives
- Variables
- TL;DR
NODE.JS
Paradigm - FP
Javascript is a multiparadigm programming language. While we could make a mix of paradigms in our code is better, focus on just one. The trend today is to focus on functional programming, both to develop a frontend or a backend.
These are some functional programming principles that are useful to know.
- Thinks in functions
- Lambda
- Curry
- Stateless
- Composing functions
- pure functions:
- Side effects
- Functor
- High order functions
- First class
- Mutations
👉 To continue reading about FP, go to this link:
https://github.com/damiancipolat/Functional_programming_in_JS
Naming conventions
How to name objects in js.
Based in the Airbnb guide points:
23.1
,23.2
,23.3
,23.6
Avoid single letter names. Be descriptive with your naming.
// badfunctionq(){}// goodfunctionquery(){}
UsecamelCase when naming objects, functions, and instances.
// badconstOBJEcttsssss={};constthis_is_my_object={};functionc(){}// goodconstthisIsMyObject={};functionthisIsMyFunction(){}
UsePascalCase only when naming constructors or classes.
// badfunctionuser(options){this.name=options.name;}constbad=newuser({name:'nope',});// goodclassUser{constructor(options){this.name=options.name;}}constgood=newUser({name:'yup',});
Useuppercase only in constants.
// allowed but does not supply semantic valueexportconstapiKey='SOMEKEY';// better in most casesexportconstAPI_KEY='SOMEKEY';
Semicolons
Based in the Airbnb guide points:
21.1
.
Why? When JavaScript encounters a line break without a semicolon, it uses a set of rules called Automatic Semicolon Insertion to determine whether or not it should regard that line break as the end of a statement, and (as the name implies) place a semicolon into your code before the line break if it thinks so. ASI contains a few eccentric behaviors, though, and your code will break if JavaScript misinterprets your line break. These rules will become more complicated as new features become a part of JavaScript. Explicitly terminating your statements and configuring your linter to catch missing semicolons will help prevent you from encountering issues
```javascript// badfunction foo() { return 'search your feelings, you know it to be foo'}// goodconst luke = {};const leia = {};[luke, leia].forEach((jedi) => { jedi.father = 'vader';});```
Comments
Standarize js comments in your projects. Visualstudio code recognize this format.
Use JSDOChttps://jsdoc.app/about-getting-started.html format.
Use block comment.
/** This is a description of the foo function. */functionfoo(){}
Use JSDOC tag to describe a function.
/*** Represents a book.* @constructor* @param {string} title - The title of the book.* @param {string} author - The author of the book.*/functionBook(title,author){}
Promises.
Change the way to handle callbacks.
- If you work with callback styled function, wrap it in a promise:
functiondoAsync(function(err,data){if(err){// error}else{// success}});
- With Promises:
constdoAsyncPomise=()=>{returnnewPromise((resolve,reject)=>{if(err)reject(err);elseresolve(..);});}
Error handling
Different ways of handle errors.
- Using sync functions:
try{makeSomething();}catch(err){rollBack();}
- Using a function that return promise:
makeSomething().then(data=>{//....}).catch(err=>{rollback(...)});
- Using into a async/await function:
construn=async()=>{try{constresult=awaitmakeSomething();}catch(err){rollBack(..)}};
- Avoid to return "error structures" to comunicate an error, is better to launch an exception.
//badconstrun=(param)=>{constresult=makeSomething(param);if(result){returnresult;}else{return{error:'processing error'};}}//goodconstrun=(param)=>{if(!param)thrownewError('Bad parameters');constresult=makeSomething(param);if(!result)thrownewError('Processing error');returnresult;}
Comparision
Improve your comparision methods.
Based in the Airbnb guide points:
15.1
,15.2
,15.3
,15.5
,15.6
,15.7
- Use === and !== over == and !=.
Conditional statements such as the if statement evaluate their expression using coercion with the ToBoolean.
https://github.com/airbnb/javascript/blob/master/README.md#comparison--ifif([0]&&[]){// true// an array (even an empty one) is an object, objects will evaluate to true}
User shorcuts for booleans.
// badif(isValid===true){// ...}// goodif(isValid){// ...}
Ternaries should not be nested and generally be single line expressions.
// badconstfoo=maybe1>maybe2?"bar":value1>value2?"baz":null;// split into 2 separated ternary expressionsconstmaybeNull=value1>value2?'baz':null;// betterconstfoo=maybe1>maybe2?'bar':maybeNull;// bestconstfoo=maybe1>maybe2?'bar':maybeNull;
Ternaries should not be nested and generally be single line expressions.
// badconstfoo=a?a:b;constbar=c?true:false;constbaz=c?false:true;// goodconstfoo=a||b;constbar=!!c;constbaz=!c;
Iterations
Handle the lopps in a functional style.
Based in the Airbnb guide points:
11.1
Don’t use iterators, prefer js higher-order functions instead of for / for..in
// badconstincreasedByOne=[];for(leti=0;i<numbers.length;i++){increasedByOne.push(numbers[i]+1);}// goodconstincreasedByOne=[];numbers.forEach((num)=>{increasedByOne.push(num+1);});
Functions
How to handle functions in a modern way.
Based in the Airbnb guide points:
7.1
,7.5
,7.6
,7.7
,7.10
,7.12
,7.13
Use named arrow function expressions instead of function declarations.
// badfunctionfoo(){// ...}// badconstfoo=()=>{// ...};
Never name a parameter arguments..
// badfunctionfoo(name,options,arguments){// ...}// goodfunctionfoo(name,options,args){// ...}``-Neverusearguments,opttouserestsyntax...instead.
javascript
// bad
function concatenateAll() {
const args = Array.prototype.slice.call(arguments);
return args.join('');
}// good
function concatenateAll(...args) {
return args.join('');
}
``Avoid side effects with default parameters..
`javascript
const b = 1;
// bad
function count(a = b++) {
console.log(a);
}
count(); // 1
count(); // 2
count(3); // 3
count(); // 3- Never mutate parameters.
`javascript// badfunction f1(obj) {obj.key = 1;}
// good
function f2(obj) {
const key = Object.prototype.hasOwnProperty.call(obj, 'key') ? obj.key : 1;
``- Never mutate parameters.
String
Best way to handle strings.
Based in the Airbnb guide points:
6.1
,6.2
,6.3
,6.4
Use single quotes '' for strings, don't mix with "".
// badconstname="Bart";// bad - template literals should contain interpolation or newlinesconstname=`Marge`;// goodconstname='Homer';
Use template string instead of concatenate string with values.
constname='Bart';constsurname='Simpson';// badconsttxt='hello mr.'+name+','+surname';// goodconst txt = `hello mr. ${name}, ${surname}`;``**[⮬ back to top](#table-of-contents)**
Destructuring
Destructuring simply implies breaking down a complex structure into simpler parts.
Based in the Airbnb guide points:
5.1
,5.2
,5.3
Use destructuring when accessing and using multiple properties of an object.
javascript// badfunction getFullName(user) { const firstName = user.firstName; const lastName = user.lastName; return `${firstName} ${lastName}`;}// goodfunction getFullName(user) { const { firstName, lastName } = user; return `${firstName} ${lastName}`;}
Use array destructuring.
javascript// badconst first = arr[0];const second = arr[1];// goodconst [first, second] = arr;``**[⮬ back to top](#table-of-contents)**
Arrays
Array manipulation practices.
Based in the Airbnb guide points:
4.1
,4.3
,4.4
,4.7
- Is important to know this array prototypes:
map
,reduce
,forEach
,filter
,find
,push
,pop
,slice
.https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/Array/prototype Use the literal syntax for array creation.
`
javascript
// bad
const items = new Array();// good
const items = [];`
- Use array spreads
...
to copy arrays:`javascript// badconst len = items.length;const itemsCopy = [];let i;
for (i = 0; i < len; i += 1) {
itemsCopy[i] = items[i];
}// good
const itemsCopy = [...items];`
- To convert an iterable object to an array, use spreads
...
instead ofArray.from
. `javascript// badconst items = new Array();
// good
const items = [];`
- Use array spreads
...
to copy arrays:`javascript// badconst len = items.length;const itemsCopy = [];let i;
for (i = 0; i < len; i += 1) {
itemsCopy[i] = items[i];
}// good
const itemsCopy = [...items];`
- Use return statements in array method callbacks:`
javascript// badinbox.filter((msg) => {const { subject, author } = msg;if (subject === 'Mockingbird') {return author === 'Harper Lee';} else {return false;}});
// good
inbox.filter((msg) => {
const { subject, author } = msg;
if (subject === 'Mockingbird') {
return author === 'Harper Lee';
}return false;
});`
- Use array spreads
Objects
Some tips of how to improve the object manipulation.
Based in the Airbnb guide points:
3.1
,3.3
,3.4
,3.6
,3.8
Use the literal syntax for object creation.
`javascript
// bad
const item = new Object();// good
const item = {};`
Use object method shorthand.
`javascript
// bad
const atom = {
value: 1,addValue: function (value) {
return atom.value + value;
},
};// good
const atom = {
value: 1,addValue(value) {
return atom.value + value;
},
};`
Use property value shorthand.
`javascript
const bart = 'Bart Simpson';// bad
const obj = {
bart: bart,
};// good
const obj = {
bart,
};`
Only quote properties that are invalididentifiers in the example is 'bla-bla'.
`javascript
// bad
const bad = {
'foo': 3,
'bar': 4,
'data-blah': 5,
};// good
const good = {
foo: 3,
bar: 4,
'bla-bla': 5,
};`
If you need to access dinamycali to one object atributte:
`javascript
const person = {
name:'Damian',
age:32
};const key = 'age';
console.log(person[key]);`
Prefer the object spread operator over Object.assign toshallow-copy objects:
`javascript
// bad
const original = { a: 1, b: 2 };
const copy = Object.assign({}, original, { c: 3 }); // copy => { a: 1, b: 2, c: 3 }// good
const original = { a: 1, b: 2 };
const copy = { ...original, c: 3 }; // copy => { a: 1, b: 2, c: 3 }`
Properties
Based in the Airbnb guide points:
12.1
,12.2
Use dot notation when accessing properties.
`
javascript
const luke = {
jedi: true,
age: 28,
};// bad
const isJedi = luke['jedi'];// good
const isJedi = luke.jedi;`
- Use bracket notation [] when accessing properties with a variable:`
javascriptconst person = {name:'Damian',age:32};
const key = 'age';
console.log(person[key]);`
- Use bracket notation [] when accessing properties with a variable:`
Primitives
The basic type data provided in js.
Based in the Airbnb guide points:
1.1
When you access a primitive type you work directly on its value.
- string
- number
- boolean
- null
- undefined
- symbol
Variables
Some points of how to handle and declare variables in javascript.
Based in the Airbnb guide points:
2.1
,2.2
,13.1
,13.2
,13.3
,13.4
,13.5
,13.8
- Avoid to use global variable in the projects.
- Avoid use
var
in variable declaration, useconst
. - If you must reassign references, use
let
instead ofconst
. - Group all your
const
and then group all yourlet
. Remove unused variables.
`
javascript
// bad
var a = 1;
var b = 2;// good
const a = 1;
const b = 2;// bad
var count = 1;
if (true) {
count += 1;
}// good, use the let.
let count = 1;
if (true) {
count += 1;
}// bad
superPower = new SuperPower();// good
const superPower = new SuperPower();`
TL;DR;
Don't use:
- No global vars.
- Declare variables using "var".
- Declare functions using "function" keyword.
- Avoid use "for" in loops.
- Array push, inmutability.
- Class.
- Use delete to remove a object atribute.
- Avoid nested if.
- else if.
- Heavy nestinghttps://www.w3.org/wiki/JavaScript_best_practices#Avoid_heavy_nesting.
- Avoid to add prototype to functions that could be used in a module.
Use:
- Common code in functions, follow D.R.Y principle.
- Shorcut notation.
- Spread operator over Object.assign (airbnb 3.8).
- Pascal case naming.
- Modularize your code in modules.
- const and let!.
- Literal syntax for object creation (airbnb 3.1).
- Computed property names when creating objects (airbnb 3.2).
- Property value shorthand (airbnb 3.4).
- Group your shorthand properties at the beginning of your objec (airbnb 3.5).
- use the literal syntax for array creation (airnbnb 4.1).
- Use array spreads ... to copy arrays. (airbnb 4.3).
- use spreads ... instead of, Array.from. (airbnb 4.4).
- Use return statements in array method callbacks (airbnb 4.7).
NPM:
Some interesting tips and commands to use in npm.
####npm init
Execute this command whenever you start a project from scratch
####npm install {dependency} --save
Execute this command using the save parameter, when you need to install a new module, the save parameter record the dependecy in the package.json
####npm install {dependency} --save--dev
Install a new dependency but only for development purposes, example unit testing.
####npm install
Will install both "dependencies" and "devDependencies" from package.json.
####npm install --dev
Run this command when you need to install only dev dependencys example into a ci/cd step to run test. Will only install "devDependencies" from package.json
####npm install --production
Will only install "dependencies" from package.json.
####npm audit
This command list all the security vulnerabilities of the dependencys installed in the package.json
####npm audit --fix
Subcommand to automatically install compatible updates to vulnerable dependencies.
Package.json:
- VERSION:
Use theversion
attribute to save the current project version follow the SEMVER rules,http://semver.org
`json
{
"name": "api",
"version": "1.0.0",
"description": "orders api",
"main": ""
}
`
SEMVER rules:
MAJOR: version when you make incompatible API changes.
MINOR: version when you add functionality in a backwards-compatible manner.
PATCH: version when you make backwards-compatible bug fixes.
- DEPENDENCIES:
Make sure you are saving the dependencies modules in the"devDependencies" section.
- SCRIPTS:
Its important to complete the script section of the package.json, the basic script should be:
`sh
npm start
npm test
npm deploy
`
Recommendations:
- Use npm mayor / npm minor things change the versions.
- Set NODENV in production.
- Split common code in modules.
- Don't use sync function for i/o;
- Use streams.
- Communicate error using exceptions.
- Try/catch if you can solve the exception.
- Good use of promises.
- Promise.all to paralellize always
- Wrap promise.all to avoid partial executions.
- Async / await instead of promise.then
- Don't use callbacksm replace them by Promise.
- Avoid heavy nesting.
- Avoid use else if.
- Avoid nested if.
- Avoid use global variables.
- Don't abuse installing modules
- Think first in use node core modules instead of search npm modules.
- Create a logger wrapper instead of use console.log, (winston)
- Create private npm modules for general purposes code used in different projects. Reutilizations.
- Avoid the "core" patterns', the idea is avoid putting the entire business code of the application in a set of npm modules
- Don't use class is better to focus in modules that export functions.
- Externalize your config, make easy the test later.
Stacks:
Some recomendatios of modules.
- For testing: Jest or Mocha / Chai / Proxyquire.
- For logging: Winston.
- For Api: Expressjs, Hapijs, Restify.
- For SQL: Sequlize.
- For Mongodb: Mongoose.
- For Serverless: Serverless framework or AWS-CDKhttps://docs.aws.amazon.com/cdk/latest/guide/getting_started.html
- For request: node-fetch or axios.
- For time: moment / moment-timezone.
- For lint: es-lint.
- For schema validation: Joi
Have fun! 🛸🐧🐲👽👆👻👺
Top comments(7)

- LocationLondon
- EducationMaster's Degree
- WorkNodeJS Developer at Atom Learning
- Joined
This is generally a good compilation, but a beginner would totally get lost in the amount of concepts, especially considering you don't explain what they are/what they mean. Consider providing links for them.
Also:
Async / await instead of promise.then
Why?? Is this based on any arguments or is it just something made up out of the blue?
I must strongly disagree, the only advantage async/await has over Promise chaining is that with async/await you can directly assign the value the promise resolves to, saving you a whopping line of code.
I personally prefer promise chaining as I find it much more flexible; maybe you don't want to pause code execution after all.

- LocationArgentina
- WorkSoftware Engineer at Fintech
- Joined
Thanks for the comment, for this documment I assume the developer has some of experience working in node.js the main idea is not a tutorial style. Is more a summary of best practices and code-style.

- Email
- LocationRomania
- WorkMath student
- Joined
Wdym by pause code execution? Async await doesnt actually pause it everywhere, just in the function you call it from.

- LocationBremen, Germany
- EducationM.Sc.
- Pronounshe/him
- WorkScientific Employee at University of Bremen
- Joined
Thank you for this summary. I would like to read more on the functional paradigm but the link is broken in👉 To continue reading about FP, go to this document.
would you mind checking and updating it?

- LocationArgentina
- WorkSoftware Engineer at Fintech
- Joined
yes sure! The link is broken, my bad. this is the link:
github.com/damiancipolat/Functiona...

Very nice summary.
Btw I think instead of "Comparision" you meant "Comparison"?
Also, my DNS servers (Cloudflare & Google) can't resolve your website's domain,damiancipolat.com
orwww.damiancipolat.com
.
3- Markdown seems to be broken afterconcatenateAll
part.
For further actions, you may consider blocking this person and/orreporting abuse