Update Javascript coding guidelines authored by Moreau Nicolas's avatar Moreau Nicolas
...@@ -28,12 +28,11 @@ You should include spaces between operators and operands, parameters, etc... ...@@ -28,12 +28,11 @@ You should include spaces between operators and operands, parameters, etc...
Example : Example :
`if(dayOfWeek === 7 && weather === 'sunny') {` ```javascript
if(dayOfWeek === 7 && weather === 'sunny') {
`goOnTrip('beach', 'car', ['ice cream', 'bucket and spade', 'beach towel']);` goOnTrip('beach', 'car', ['ice cream', 'bucket and spade', 'beach towel']);
}
`}` ```
Other rules : Other rules :
```plaintext ```plaintext
...@@ -56,21 +55,16 @@ Use JS-style comments to comment code that isn't self-documenting: ...@@ -56,21 +55,16 @@ Use JS-style comments to comment code that isn't self-documenting:
Put your comments on separate lines preceding the code they are referring to: Put your comments on separate lines preceding the code they are referring to:
`function myFunc() {` ```javascript
function myFunc() {
`// Output the string 'Hello' to the browser's JS console` // Output the string 'Hello' to the browser's JS console
console.log('Hello');
`console.log('Hello');` // Create a new paragraph, fill it with content, and append it
let para = document.createElement('p');
`// Create a new paragraph, fill it with content, and append it to the` para.textContent = 'My new paragraph';
document.body.appendChild(para);
`let para = document.createElement('p');` }
```
`para.textContent = 'My new paragraph';`
`document.body.appendChild(para);`
`}`
Also note that you should leave a space between the slashes and the comment, in each case. Also note that you should leave a space between the slashes and the comment, in each case.
...@@ -81,16 +75,17 @@ Also note that you should leave a space between the slashes and the comment, in ...@@ -81,16 +75,17 @@ Also note that you should leave a space between the slashes and the comment, in
For variable names use lowerCamelCasing, and use concise, human-readable, semantic names where appropriate. For variable names use lowerCamelCasing, and use concise, human-readable, semantic names where appropriate.
Do this: Do this:
```javascript
`let playerScore = 0;` let playerScore = 0;
let speed = distance / time;
`let speed = distance / time;` ```
not this : not this :
`let thisIsaveryLONGVariableThatRecordsPlayerscore345654 = 0;` ```javascript
let thisIsaveryLONGVariableThatRecordsPlayerscore345654 = 0;
`let s = d/t;` let s = d/t;
```
The only place where it is OK to not use human-readable semantic names is where a very common recognized convention exists, such as using i, j, etc. for loop iterators. The only place where it is OK to not use human-readable semantic names is where a very common recognized convention exists, such as using i, j, etc. for loop iterators.
...@@ -100,17 +95,18 @@ When declaring variables and constants, use the let and const keywords, not var. ...@@ -100,17 +95,18 @@ When declaring variables and constants, use the let and const keywords, not var.
If a variable will not be reassigned, prefer const: If a variable will not be reassigned, prefer const:
`const myName = 'Chris';` ```javascript
const myName = 'Chris';
`console.log(myName);` console.log(myName);
```
Otherwise, use let: Otherwise, use let:
`let myAge = '40';` ```javascript
let myAge = '40';
`myAge++;` myAge++;
console.log('Happy birthday!');
`console.log('Happy birthday!');` ```
## ##
...@@ -120,15 +116,17 @@ Otherwise, use let: ...@@ -120,15 +116,17 @@ Otherwise, use let:
Ternary operators should be put on a single line: Ternary operators should be put on a single line:
`let status = (age >= 18) ? 'adult' : 'minor';` ```javascript
let status = (age >= 18) ? 'adult' : 'minor';
```
Not nested: Not nested:
`let status = (age >= 18)` ```javascript
let status = (age >= 18)
`? 'adult'` ? 'adult'
: 'minor';
`: 'minor';` ```
### Use strict equality ### Use strict equality
...@@ -136,15 +134,17 @@ Always use strict equality and inequality. ...@@ -136,15 +134,17 @@ Always use strict equality and inequality.
Do this: Do this:
`name === 'Chris';` ```javascript
name === 'Chris';
`age !== 25;` age !== 25;
```
Not this: Not this:
`name == 'Chris';` ```javascript
name == 'Chris';
`age != 25;` age != 25;
```
### Use shortcuts for boolean tests ### Use shortcuts for boolean tests
...@@ -158,11 +158,11 @@ Use shortcuts for boolean tests — use x and !x, not x === true and x === false ...@@ -158,11 +158,11 @@ Use shortcuts for boolean tests — use x and !x, not x === true and x === false
- There should be a space between the parentheses and the opening curly brace. - There should be a space between the parentheses and the opening curly brace.
``` ```
`if(iceCream) {` ```javascript
if(iceCream) {
`alert('Woo hoo!');` alert('Woo hoo!');
}
`}` ```
## Strings ## Strings
...@@ -172,32 +172,35 @@ For inserting values into strings, use string literals. ...@@ -172,32 +172,35 @@ For inserting values into strings, use string literals.
Do this: Do this:
`let myName = 'Chris';` ```javascript
let myName = 'Chris';
`` console.log(`Hi! I'm ${myName}!`); `` console.log(`Hi! I'm ${myName}!`);
```
Not this : Not this :
`let myName = 'Chris';` ```javascript
let myName = 'Chris';
`console.log('Hi! I\'m' + myName + '!');` console.log('Hi! I\'m' + myName + '!');
```
### Use textContent, not innerHTML ### Use textContent, not innerHTML
When inserting strings into DOM nodes, use Node.textContent: When inserting strings into DOM nodes, use Node.textContent:
`let text = 'Hello to all you good people';` ```javascript
let text = 'Hello to all you good people';
`const para = document.createElement('p');` const para = document.createElement('p');
para.textContent = text;
`para.textContent = text;` ```
\ \
Not Element.innerHTML: Not Element.innerHTML:
`let text = 'Hello to all you good people';` ```javascript
let text = 'Hello to all you good people';
`const para = document.createElement('p');` const para = document.createElement('p');
```
textContent is a lot more efficient, and less error-prone than innerHTML. textContent is a lot more efficient, and less error-prone than innerHTML.
...@@ -209,51 +212,40 @@ When loops are required, choose an appropriate loop out of the available ones (f ...@@ -209,51 +212,40 @@ When loops are required, choose an appropriate loop out of the available ones (f
When using for/for...of loops, make sure to define the initializer properly, with a let keyword: When using for/for...of loops, make sure to define the initializer properly, with a let keyword:
`let cats = ['Athena', 'Luna'];` ```javascript
let cats = ['Athena', 'Luna'];
`for(let i of cats) {` for(let i of cats) {
console.log(i);
`console.log(i);` }
```
`}`
Not : Not :
`let cats = ['Athena', 'Luna'];` ```javascript
let cats = ['Athena', 'Luna'];
`for(i of cats) {` for(i of cats) {
console.log(i);
`console.log(i);` }
```
`}`
### Switch statements ### Switch statements
Format switch statements like this: Format switch statements like this:
`let expr = 'Papayas';` ```javascript
let expr = 'Papayas';
`switch(expr) {` switch(expr) {
case 'Oranges':
` case 'Oranges':` console.log('Oranges are $0.59 a pound.');
break;
` console.log('Oranges are $0.59 a pound.');` case 'Papayas':
console.log('Mangoes and papayas are $2.79 a pound.');
` break;` // expected output: "Mangoes and papayas are $2.79 a pound."
break;
` case 'Papayas':` default:
console.log(`Sorry, we are out of ${expr}`);
` console.log('Mangoes and papayas are $2.79 a pound.');` }
```
` // expected output: "Mangoes and papayas are $2.79 a pound."`
` break;`
` default:`
`` console.log(`Sorry, we are out of ${expr}`); ``
`}`
## Functions and objects ## Functions and objects
...@@ -263,11 +255,11 @@ For function names use lowerCamelCasing, and use concise, human-readable, semant ...@@ -263,11 +255,11 @@ For function names use lowerCamelCasing, and use concise, human-readable, semant
Do this: Do this:
`function sayHello() {` ```javascript
function sayHello() {
`alert('Hello!');` alert('Hello!');
};
`};` ```
### Defining functions ### Defining functions
...@@ -275,29 +267,27 @@ Where possible, use the function declaration to define functions over function e ...@@ -275,29 +267,27 @@ Where possible, use the function declaration to define functions over function e
Do this: Do this:
`function sum(a, b) {` ```javascript
function sum(a, b) {
`return a + b;` return a + b;
}
`}`
Not this : Not this :
`let sum = function(a, b) {` ```javascript
let sum = function(a, b) {
`return a + b;` return a + b;
}
`}` ```
When using anonymous functions inside a method that requires a function as a parameter, it is acceptable (although not required) to use an arrow function to make the code shorter and cleaner. When using anonymous functions inside a method that requires a function as a parameter, it is acceptable (although not required) to use an arrow function to make the code shorter and cleaner.
`const array1 = [1, 2, 3, 4];` ```javascript
const array1 = [1, 2, 3, 4];
`let sum = array1.reduce((a, b) =>` let sum = array1.reduce((a, b) =>
a + b
`a + b` );
```
`);`
### Creating objects ### Creating objects
...@@ -305,11 +295,15 @@ Use literals — not constructors — for creating general objects (i.e., when c ...@@ -305,11 +295,15 @@ Use literals — not constructors — for creating general objects (i.e., when c
Do this: Do this:
`let myObject = { };` ```javascript
let myObject = { };
```
Not this : Not this :
`let myObject = new Object();` ```javascript
let myObject = new Object();
```
### Object classes ### Object classes
...@@ -317,33 +311,27 @@ Use ES class syntax for objects, not old-style constructors. ...@@ -317,33 +311,27 @@ Use ES class syntax for objects, not old-style constructors.
For example: For example:
`class Person {` ```javascript
class Person {
` constructor(name, age, gender) {` constructor(name, age, gender) {
this.name = name;
` this.name = name;` this.age = age;
this.gender = gender;
` this.age = age;` }
` this.gender = gender;` greeting() {
console.log(`Hi! I'm ${this.name}`);
` }` };
}
` greeting() {` ```
`` console.log(`Hi! I'm ${this.name}`); ``
` };`
`}`
Use _extends_ for inheritance: Use _extends_ for inheritance:
`class Teacher extends Person {` ```javascript
class Teacher extends Person {
`...` ...
}
`}` ```
### Object naming ### Object naming
...@@ -351,17 +339,14 @@ When defining an object class (as seen above), use UpperCamelCasing (also known ...@@ -351,17 +339,14 @@ When defining an object class (as seen above), use UpperCamelCasing (also known
When defining an object instance, either a literal or via a constructor, use lowerCamelCase for the instance name: When defining an object instance, either a literal or via a constructor, use lowerCamelCase for the instance name:
`let hanSolo = new Person('Han Solo', 25, 'male');` ```javascript
let hanSolo = new Person('Han Solo', 25, 'male');
`let hanSolo = {` let hanSolo = {
name: 'Han Solo',
`name: 'Han Solo',` age: 25,
gender: 'male'
`age: 25,` }
```
`gender: 'male'`
`}`
## Arrays ## Arrays
...@@ -371,41 +356,49 @@ Use literals — not constructors — for creating arrays: ...@@ -371,41 +356,49 @@ Use literals — not constructors — for creating arrays:
Do this: Do this:
`let myArray = [ ];` ```javascript
let myArray = [ ];
```
Not this : Not this :
`let myArray = new Array(length);` ```javascript
let myArray = new Array(length);
```
### Adding to an array ### Adding to an array
When adding items to an array, use push(), not direct assignment. Given the following array: When adding items to an array, use push(), not direct assignment. Given the following array:
`const pets = [];` ```javascript
const pets = [];
```
Do this : Do this :
`pets.push('cat');` ```javascript
pets.push('cat');
```
not this : not this :
`pets[pets.length] = 'cat';` ```javascript
pets[pets.length] = 'cat';
```
## Error handling ## Error handling
If certain states of your program throw uncaught errors, they will halt execution and potentially reduce the usefulness of the example. You should therefore catch errors using a try...catch block: If certain states of your program throw uncaught errors, they will halt execution and potentially reduce the usefulness of the example. You should therefore catch errors using a try...catch block:
`try {` ```javascript
try {
`console.log(results);` console.log(results);
}
`}`
`catch(e) {`
`console.error(e);`
`}` catch(e) {
console.error(e);
}
````
## Documenting code ## Documenting code
...@@ -419,7 +412,7 @@ JSDoc comments should generally be placed immediately before the code being docu ...@@ -419,7 +412,7 @@ JSDoc comments should generally be placed immediately before the code being docu
### Documenting a function ### Documenting a function
``` ```javascript
/** /**
* Returns the sum of a and b * Returns the sum of a and b
* @param {number} a * @param {number} a
...@@ -433,7 +426,7 @@ function sum(a, b) { ...@@ -433,7 +426,7 @@ function sum(a, b) {
### Documenting a class ### Documenting a class
``` ```javascript
/** /**
* Class representing a dot. * Class representing a dot.
* @extends Point * @extends Point
... ...
......