Common JavaScript Mistakes and Best Practices

ยท

10 min read

JavaScript is a powerful and versatile programming language, but it's easy to make mistakes that can lead to unexpected behaviour or errors in your code. In this guide, we'll highlight some common mistakes and provide best practices to avoid them.

1. Misusing Assignment Operator (=) vs Comparison Operator (==)

JavaScript programs may generate unexpected results if a programmer accidentally uses an assignment operator ( = ), instead of a comparison operator ( == ) in an if statement.

This if statement returns false (as expected) because x is not equal to 10:

let x = 0;
if (x == 10)

This if statement returns true (maybe not as expected), because 10 is true:

let x = 0;
if (x = 10)

This if statement returns false (maybe not as expected), because 0 is false:

let x = 0;
if (x = 0)

Note:- An assignment always returns the value of the assignment.

2. Understanding Loose vs Strict Comparison

In regular comparison, data type does not matter. This if statement returns true:

let x = 10;
let y = "10";
if (x == y)

In strict comparison, data type does matter. This if statement returns false:

let x = 10;
let y = "10";
if (x === y)

It is a common mistake to forget that switch statements use strict comparison:

This case switch will display an alert:

let x = 10;
switch(x) {
    case 10: alert("Hello");
}

This case switch will not display an alert:

let x = 10;
switch(x) {
    case "10": alert("Hello");
}

3. Handling Addition vs Concatenation

Addition is about adding numbers.

Concatenation is about adding strings.

In JavaScript, both operations use the same + operator.

Because of this, adding a number as a number will produce a different result from adding a number as a string:

let x = 10;
x = 10 + 5; // Now x is 15

let y = 10;
y += "5"; // Now y is "105"

When adding two variables, it can be difficult to anticipate the result:

let x = 10;
let y = 5;
let z = x + y; // Now z is 15

let x = 10;
let y = "5";
let z = x + y; // Now z is "105"

4. Dealing with Floating-Point Precision

JavaScript uses 64-bit floating-point numbers to represent all numbers, which can lead to precision issues when dealing with decimals. Use appropriate techniques to handle floating-point arithmetic accurately.

let x = 0.1;
let y = 0.2;
let z = x + y // the result in z will not be 0.3

To solve the problem above, it helps to multiply and divide:

let z = (x * 10 + y * 10) / 10; // z will be 0.3

5. Properly Formatting Strings

JavaScript will allow you to break a statement into two lines:

let x =
"Hello World!";

But, breaking a statement in the middle of a string will not work:

let x = "Hello
World!";

Always use a backslash \ if you need to break a statement within a string.

let x = "Hello \
World!";

6. Watch for Misplaced Semicolons

Misplaced semicolons can lead to unexpected code behaviour. Always place semicolons appropriately to avoid unintended consequences. Because of a misplaced semicolon, this code block will execute regardless of the value of x:

if (x == 19);
{
    // code block
}

7. Avoid Breaking a Return Statement

It is a default JavaScript behaviour to close a statement automatically at the end of a line.

Because of this, these two examples will return the same result:

function myFunction(a) {
    let power = 10
    return a * power
}
function myFunction(a) {
    let power = 10;
    return a * power;
}

JavaScript will also allow you to break a statement into two lines.

Because of this, the below example will also return the same result:

function myFunction(a) {
    let
    power = 10;
    return a * power;
}

But, what will happen if you break the return statement into two lines like this:

function myFunction(a) {
    let
    power = 10;
    return
    a * power;
}

The function will return undefined!

Why? Because JavaScript thought you meant:

function myFunction(a) {
    let
    power = 10;
    return;
    a * power;
}

Explanation

If a statement is incomplete like:

let

JavaScript will try to complete the statement by reading the next line:

power = 10;

But since this statement is complete:

return

JavaScript will automatically close it like this:

return;

This happens because closing (ending) statements with a semicolon are optional in JavaScript.

JavaScript will close the return statement at the end of the line because it is a complete statement.

Note:- Never break a return statement.

To refine the technical blog on common JavaScript mistakes and best practices, we can improve the structure, and formatting, and add additional context and explanations to make it more informative and user-friendly.

8. Accessing Arrays with Named Indexes

Many programming languages support arrays with named indexes.

Arrays with named indexes are called associative arrays (or hashes).

JavaScript does not support arrays with named indexes.

In JavaScript, arrays use numbered indexes:

const person = [];
person[0] = "John";
person[1] = "Doe";
person[2] = 46;
person.length; // person.length will return 3
person[0]; // person[0] will return "John"

In JavaScript, objects use named indexes.

If you use a named index, when accessing an array, JavaScript will redefine the array to a standard object.

After the automatic redefinition, array methods and properties will produce undefined or incorrect results:

const person = [];
person["firstName"] = "John";
person["lastName"] = "Doe";
person["age"] = 46;
person.length; // person.length will return 0
person[0]; // person[0] will return undefined

9. Be Mindful of Trailing Commas

Trailing commas in object and array definition are legal in ECMAScript 5.

//Object
person = {firstName:"John", lastName:"Doe", age:46,}
//array
points = [40, 100, 1, 5, 25, 10,];

Note:- WARNING !! Internet Explorer 8 will crash. JSON does not allow trailing commas.

//JSON
person = {"firstName":"John", "lastName":"Doe", "age":46}
points = [40, 100, 1, 5, 25, 10];

10. Differentiating Undefined and Null

JavaScript allows objects, variables, properties, and methods to be undefined or null. Be mindful of the differences and test for both conditions appropriately.

In addition, empty JavaScript objects can have the value null.

This can make it a little bit difficult to test if an object is empty.

You can test if an object exists by testing if the type is undefined :

if (typeof myObj === "undefined")

But you cannot test if an object is null, because this will throw an error if the object is undefined :

//incorrect
if (myObj === null)

To solve this problem, you must test if an object is not null, and not undefined.

But this can still throw an error:

//incorrect
if (myObj !== null && typeof myObj !== "undefined")

Because of this, you must test for not undefined before you can test for not null :

if (typeof myObj !== "undefined" && myObj !== null)

JavaScript Style Guide

Always use the same coding conventions for all your JavaScript projects.

11. JavaScript Coding Conventions

Coding conventions are style guidelines for programming. They typically cover:

  1. Naming and declaration rules for variables and functions.

  2. Rules for the use of white space, indentation, and comments.

  3. Programming practices and principles.

Coding conventions secure quality:

  1. Improve code readability

  2. Make code maintenance easier

Coding conventions can be documented rules for teams to follow, or just be your coding practice.

Note:- This page describes the general JavaScript code conventions used by W3Schools. You should also read the next chapter "Best Practices", and learn how to avoid coding pitfalls.

12. Variable Names

At W3schools we use camelCase for identifier names (variables and functions).

All names start with a letter.

At the bottom of this page, you will find a wider discussion about naming rules.

firstName = "John";
lastName = "Doe";
price = 19.90;
tax = 0.20;
fullPrice = price + (price * tax);

13. Spaces Around Operators

Always put spaces around operators ( = + - * / ), and after commas:

let x = y + z;
const myArray = ["Volvo", "Saab", "Fiat"];

14. Code Indentation

Always use 2 spaces for indentation of code blocks:

function toCelsius(fahrenheit) {
    return (5 / 9) * (fahrenheit - 32);
}

Note:- Do not use tabs (tabulators) for indentation. Different editors interpret tabs differently.

15. Statement Rules

General rules for simple statements:

  1. Always end a simple statement with a semicolon.
const cars = ["Volvo", "Saab", "Fiat"];
const person = {
    firstName: "John",
    lastName: "Doe",
    age: 50,
    eyeColor: "blue"
};

General rules for complex (compound) statements:

  1. Put the opening bracket at the end of the first line.

  2. Use one space before the opening bracket.

  3. Put the closing bracket on a new line, without leading spaces.

  4. Do not end a complex statement with a semicolon.

//functions
function toCelsius(fahrenheit) {
    return (5 / 9) * (fahrenheit - 32);
}
//loops
for (let i = 0; i < 5; i++) {
    x += i;
}
//conditionals
if (time < 20) {
    greeting = "Good day";
} else {
    greeting = "Good evening";
}

16. Object Rules

General rules for object definitions:

  1. Place the opening bracket on the same line as the object name.

  2. Use a colon plus one space between each property and its value.

  3. Use quotes around string values, not around numeric values.

  4. Do not add a comma after the last property-value pair.

  5. Place the closing bracket on a new line, without leading spaces.

  6. Always end an object definition with a semicolon.

const person = {
    firstName: "John",
    lastName: "Doe",
    age: 50,
    eyeColor: "blue"
};

Short objects can be written compressed, on one line, using spaces only between properties, like this:

const person = {firstName:"John", lastName:"Doe", age:50,
eyeColor:"blue"};

17. Line Length < 80

For readability, avoid lines longer than 80 characters.

If a JavaScript statement does not fit on one line, the best place to break it is after an operator or a comma.

document.getElementById("demo").innerHTML =
"Hello Dolly.";

18. Naming Conventions

Always use the same naming convention for all your code. For example:

  1. Variable and function names are written as camelCase

  2. Global variables written in UPPERCASE (We don't, but it's quite common)

  3. Constants (like PI) written in UPPERCASE

Should you use hyphens, camelCase, or under_scores in variable names?

This is a question programmers often discuss. The answer depends on who you ask:

Hyphens in HTML and CSS:

HTML5 attributes can start with data- (data-quantity, data-price).

CSS uses hyphens in property names (font size).

Note:- Hyphens can be mistaken as subtraction attempts. Hyphens are not allowed in JavaScript names.

Underscores:

Many programmers prefer to use underscores (date_of_birth), especially in SQL databases.

Underscores are often used in PHP documentation.

PascalCase:

PascalCase is often preferred by C programmers.

camelCase:

camelCase is used by JavaScript itself, jQuery, and other JavaScript libraries.

Note:- Do not start names with a $ sign. It will put you in conflict with many JavaScript library names.

19. Loading JavaScript in HTML

Use simple syntax for loading external scripts (the type attribute is not necessary):

<script src="myscript.js"></script>

20. Accessing HTML Elements

A consequence of using "untidy" HTML styles, might result in JavaScript errors.

These two JavaScript statements will produce different results:

const obj = getElementById("Demo")
const obj = getElementById("demo")

If possible, use the same naming convention (as JavaScript) in HTML.

Visit the HTML Style Guide.

21. File Extensions

HTML files should have a .html extension (.htm is allowed).

CSS files should have a .css extension.

JavaScript files should have a .js extension.

22. Use Lower Case File Names

Most web servers (Apache, Unix) are case-sensitive about file names:

london.jpg cannot be accessed as London.jpg.

Other web servers (Microsoft, IIS) are not case-sensitive:

london.jpg can be accessed as London.jpg or london.jpg.

If you use a mix of upper and lower case, you have to be extremely consistent.

If you move from a case-insensitive to a case-sensitive server, even small errors can break your website.

To avoid these problems, always use lowercase file names (if possible).

23. Performance

Coding conventions are not used by computers. Most rules have little impact on the execution of programs.

Indentation and extra spaces are not significant in small scripts.

For code in development, readability should be preferred. Larger production scripts should be minimized.

Conclusion

Understanding these common JavaScript pitfalls and adopting best practices will help you write more reliable and maintainable code. Always follow a consistent coding style and stay informed about JavaScript updates and conventions to improve the quality of your code.

Remember, learning from mistakes is a crucial aspect of becoming a proficient JavaScript developer. Keep coding, keep learning, and always strive for excellence. Happy coding! ๐Ÿš€

ย