To ensure clarity, readability, and maintainability in our project, it is crucial to follow consistent coding conventions. Below are the recommended practices for JavaScript with specific naming conventions.
- Use
const
andlet
- Strict Mode
- Function Expressions
- Shallow Clone and Deep Clone
- Array Method and loop
- Conditional Statements
- Naming Conventions
- Avoid Global Variables
- Comments and JSDoc
Explanation: const
is for values that do not change, and let
is for variables that can be reassigned. Avoid var
to prevent scope issues.
const MAX_USERS = 100; // constant value
let userName = "John"; // variable value
Explanation: Enabling strict mode helps catch common coding errors and "unsafe" actions such as defining global variables.
"use strict";
function myFunction() {
// code
}
Explanation: Use arrow functions for shorter syntax and lexical this
binding.
const add = (a, b) => a + b;
Explanation: In many cases, we need to create a copy of an object or an array. There are two types of cloning:
-
Shallow Clone: Creates a new object but copies the references to the original data. Changes in the new object will affect the original object. We can use
Object.assign()
or the spread operator (...
) for shallow cloning.map
,filter
, andreduce
,concat
,slice
are also used for shallow cloning but with some differences in behavior.Find more information in the mdn documentation.
const original = { a: 1, b: { c: 2 } }; const shallowClone = { ...original };
-
Deep Clone: Creates a new object and copies the data recursively. Changes in the new object will not affect the original object. Prefer use
structuredClone
for deep cloning, this new method is available in modern browsers.Find more information in the mdn documentation.
const original = { a: 1, b: { c: 2 } }; const clone = structuredClone(original);
Performance Considerations: When working with arrays, consider the performance implications of different methods and loops. Choose the appropriate approach based on the size of the dataset and the complexity of the operation.
map
andfilter
Methods: Excellent for readability and functional programming, but can be slower due to the creation of new arrays. Use with caution for very large datasets. Find more information in the map mdn documentation.reduce
Method: Powerful for complex reductions but can be slower; use when the operation justifies the overhead.- Classic
for
Loop: Best for performance-critical applications, especially with large datasets. for...of
Loop: More readable but slightly slower; good for most use cases.forEach
Method: Convenient but slower due to function call overhead; avoid for very large datasets.while
anddo...while
Loops: Useful for unknown iterations but can be error-prone if not managed carefully.
Explanation: Use array methods for readability and functional programming. Be cautious with very large datasets due to performance considerations.
Find more information in the Array mdn documentation.
- Usage: For transforming each element of an array and returning a new array of the same length.
- Performance: Slower than
for
loops for very large arrays due to the creation of a new array. - Example:
const numbers = [1, 2, 3, 4]; const doubled = numbers.map((num) => num * 2); console.log(doubled); // [2, 4, 6, 8]
- Usage: For creating a new array containing only the elements that pass a specific test.
- Performance: Similar to
map
, slower for very large arrays due to the creation of a new array. - Example:
const numbers = [1, 2, 3, 4, 5]; const evenNumbers = numbers.filter((num) => num % 2 === 0); console.log(evenNumbers); // [2, 4]
- Usage: For accumulating the values of an array into a single value (e.g., sum, product).
- Performance: Can be slower due to the complexity of the operation, but very powerful for reducing data.
- Example:
const numbers = [1, 2, 3, 4]; const sum = numbers.reduce((acc, num) => acc + num, 0); console.log(sum); // 10
Explanation: Use classic for
loops for performance-critical applications and for...of
loops for readability. Avoid forEach
for very large datasets.
- Usage: For simple iterations over arrays or numeric sequences.
- Performance: Generally the fastest for large datasets due to minimal overhead.
- Example:
for (let i = 0; i < array.length; i++) { console.log(array[i]); }
- Usage: For iterating directly over the elements of an array or any iterable object.
- Performance: Slightly slower than the classic
for
loop but more readable. - Example:
for (const element of array) { console.log(element); }
- Usage: To apply a function to each element of an array. Note that
forEach
cannot be interrupted withbreak
orcontinue
. - Performance: Generally slower than
for
andfor...of
loops due to function call overhead. So use it for a small amount of data. - Example:
array.forEach((element) => { console.log(element); });
- Usage: For loops where the number of iterations is not known in advance.
- Performance: Similar to the classic
for
loop, but can be more error-prone if not carefully managed. - Example:
let i = 0; while (i < 10) { console.log(i); i++; }
- Usage: Use
break
to exit a loop early andcontinue
to skip the current iteration and proceed to the next one. - Example:
for (let i = 0; i < 10; i++) { if (i === 5) { break; // Exit the loop when i is 5 } if (i % 2 === 0) { continue; // Skip even numbers } console.log(i); }
Use if...else
for simple and clear conditional logic.
if (condition) {
// code if the condition is true
} else {
// code if the condition is false
}
Use the ternary operator for concise conditional assignments.
const result = condition ? "true" : "false";
Use switch
for multiple conditions based on a single variable. This can be more readable than multiple if...else if
statements.
switch (value) {
case 1:
// code for case 1
break;
case 2:
// code for case 2
break;
default:
// default code
}
Use logical operators for short-circuit evaluation to write concise and efficient conditions.
const value = someCondition && "defaultValue";
const value = someCondition || "defaultValue";
Avoid deeply nested conditions by using guard clauses or returning early from functions.
function example(value) {
if (!value) {
return "No value";
}
// code if value is truthy
}
Always use ===
instead of ==
for comparison to avoid type coercion issues.
if (value === 10) {
// code if value is exactly 10
}
Consistency in naming improves code readability and maintainability.
let userAge = 25;
function getUserAge() {
return userAge;
}
var hasOwner = true;
var isTrained = false;
var hasVaccinations = true;
class UserProfile {
constructor(name) {
this.name = name;
}
}
const DAYS_IN_WEEK = 7;
const MONTHS_IN_YEAR = 12;
const MAX_DOG_WEIGHT = 150;
dog - cartoon.js;
dog - breed - information.js;
- Minimize the use of global variables to prevent memory leaks and conflicts. Scope variables as tightly as possible.
- Example:
(function () { const localVariable = "I am local"; console.log(localVariable); })();
Use comments to explain complex code, logic, or algorithms. Follow the JSDoc standard for documenting functions, classes, and variables.
/**
* Represents a user.
* @constructor
* @param {string} name - The user's name.
* @param {number} age - The user's age.
*/
function User(name, age) {
this.name = name;
this.age = age;
}