JavaScript Mistakes

Common JavaScript Mistakes to Avoid

There’re some very common programming mistakes that we want to avoid to keep our code clean and readable.

In this article, we’ll look at them and how to avoid each one.

Too Many Things in One Function

One function should do one thing only, which is whatever is indicated on their own.

If there’s something else, then it should be moved to its own function. Having too many things in one function makes it hard to read and follow.

For example, if there’s a function that gets both the subtotal and the taxes, then they should be split into 2 separate functions since they’re different.

Commented-Out Code

Commented-out code are code that won’t run. Therefore, they shouldn’t be there after we’re done with working on that part of our code.

Once we’re done, we should remove the commented-out or uncomment them.

Either way, the final product shouldn’t have commented out code in it.

Variable Names That Aren’t Descriptive

Naming variables in ways that don’t convey their meaning frustrate readers and ourselves once we forgot about that code we wrote and came back to it.

Therefore, we should name variables with names that describe what they hold.

Instead of writing let x; , write something like let numApples so that we know that our variable will hold the number of apples.

Magic Numbers and String

We shouldn’t have magic numbers and strings. Those are values that appear in multiple and mean the same thing, but it’s not explained explicitly in the code.

For instance, if we have the following code:

for (let i = 0; i < 10; i++) {  

Then we don’t know what the 10 means. Instead, we should set it to a named constant so that we know what it means.

For instance, we can write:

const numApples = 10;  
for (let i = 0; i < numApples; i++) {  

Now we know that 10 actually means the number of apples.

Messy Code Formatting

Messy code formatting makes code hard to read, so we should clean it up with a linter or a code formatter.

There’re plenty of choices out there, so we can use something like Prettier or ESLint to do the tidying automatically.

Hard Coding Values

We should never hard code values into our code, especially if they’re secrets. Instead, we should keep them as environment variables and read all the values from there.

There’re many ways to do that. For the front end, Angular, React, and Vue, for example, all have places to keep variables to keep variables for different environments in different files.

For the back end, we can use something like the dotenv package to read environment variables from a .env file so that we don’t have to hard code them.

The .env file shouldn’t be checked in, so we don’t have secrets in our code repositories.

Photo by Jens Johnsson on Unsplash

Repetitive Code

The repetitive code is bad. If we change something that repeats, we have to change them in all the places that they’re repeated.

Instead, we should move the common parts into their own file so that they can be used in multiple places.

The do not repeat yourself (DRY) principle applies everywhere. If we’re copying and pasting and using them exactly as is, then we should move them to a shared location.

Not Backing Up Code

We should manage our code with Git so that we can have a local and remote repo for our code.

This way we can keep one copy in a remote location automatically. Also, we can revert bad code easily and fetch code from earlier commits easily.

We can’t do that without version control.

If we don’t have our code backed up, then we may lose everything if something goes wrong.

Complicated Code

Complex code should be simplified so that we can understand them more easily.

We should also break them up into smaller parts so that we can reuse stuff and also have individual parts that are easy to read and test.


These common mistakes can easily be avoided if we’re careful about what we’re doing.

Breaking stuff to small pieces is always good, as with keeping things simple and not repeating things.

Commented out should be gone, and variables and values that aren’t descriptive should also be replaced with something with more meaning.

JavaScript Mistakes

JavaScript Mistakes — Strict Mode

JavaScript is a very forgiving language. It’s easy to write code that runs but has mistakes in it.

In this article, we’ll look at the benefits of using the strict mode directive.

Add Use Strict Mode Directive in Our Scripts

If we’re using old-school JavaScript script files, then we should add the 'use strict' directive into the top of our script.

Strict mode eliminates lots of silent errors by changing them to throw errors.

It also fixes mistakes that make optimizing our JavaScript code hard to increase their performance.

Also, it bans syntax that may be used in future JavaScript versions. Keywords like class can’t be used to declare variables, for example.

Strict mode can be applied to the whole script by putting the directive at the top or just in the function level by putting it in functions.

However, we should just apply it everywhere since it brings lots of benefits.

For instance, we can’t declare variables accidentally with 'use strict' on:

'use strict';
x = 1;

Since we have the 'use strict' directive on top of our script, we’ll get an error with the x = 1 expression since we haven’t declared x yet.

Without strict mode, this would create a global variable called x and assign 1 to it and pollute the global scope.

That isn’t good because it may overwrite another global variable with the same name.

Also, we can assign values to another global value like undefined or Infinity :

With strict mode on, code like the following will throw a TypeError:

var undefined = 1;
var Infinity = 1;

Assigning values to a non-writable property will also fail with a TypeError thrown:

var obj = {};
Object.defineProperty(obj, 'foo', { value: 42, writable: false }); = 9;

We also wouldn’t be able to add properties that has preventExtensions called on it to prevent that:

var obj = {};
Object.preventExtensions(obj); = 'a';

The code above would throw a TypeError.

Attempting to delete undeletable properties will also throw an error. If we write something like:

'use strict';
delete Object.prototype;

Then we’ll get a TypeError.

Strict mode also requires function parameters to be unique. For instance, if we write:

'use strict';
function add(a, a, c) {
  return a + a + c;

Then we’ll get an ‘Uncaught SyntaxError: Duplicate parameter name not allowed in this context’ error since we have JavaScript strict mode on.

Also, it prevents numbers with a leading 0 from being used. The leading zero for octal numbers is rarely used and developers often assume that it’s still a decimal number.

Therefore if we have the following the strict mode throws an error:

'use strict';
var sum = 015 + 222;

If we run that, we get ‘Uncaught SyntaxError: Octal literals are not allowed in strict mode.’

The with statement is prohibited in strict mode. With strict mode, confusing code like this is prohibited:

'use strict';
var x = 17;
with(obj) {

The code above is confusing because x can either be obj.x or just x . It’s hard to tell what it’s referring to.

With strict mode on as we have above, we get ’Uncaught SyntaxError: Strict mode code may not include a with statement’.

Doing anything to arguments or eval will also return syntax errors, so code like the following:

'use strict';
eval = 'foo';

Then we get ‘Uncaught SyntaxError: Unexpected eval or arguments in strict mode’ when we run the code above since we have JavaScript strict mode on.

We shouldn’t use these entities regardless of whether JavaScript strict mode is on, so it’s good that strict mode prevents expressions like these from running at least.

With strict mode on, the this value passed into call , apply , or bind aren’t boxed into an object.

Therefore, the original value is preserved if we pass in a primitive value. For instance, if we have:

'use strict';

function fn() {
  return this;
console.log( === 1);

Then we get 1 returned from fn instead of new Number(1) , so we get that the console log output returns true .

Strict mode is enabled automatically for modules so we don’t need the directive on top of our code.


With so many benefits to strict mode, we should always enable it in old-school scripts.

If we use JavaScript modules, then it’s enabled by default, so we don’t have to worry about it.

We just have to put 'use strict' on top of all our scripts.

JavaScript Mistakes

JavaScript Mistakes — Wrappers and Objects

JavaScript is a very forgiving language. It’s easy to write code that runs but has mistakes in it.

In this article, we’ll look at bad constructs that we shouldn’t use, like manually create wrapper objects for primitive values, octal literals, and assigning parameters to a different value.

No Primitive Wrapper Instances

For strings, numbers, and boolean, we shouldn’t create wrapper objects manually with the new operator.

They’re needed so that we can call methods of primitive values, where the JavaScript interpreter will automatically create the wrapper and then call the methods. Once it’s done calling the method we want to call, then they’re automatically destroyed.

However, there’s no reason to create them manually. They’re confusing since they have the type 'object' .

For instance, if we have the following expressions:

typeof new String("foo");
typeof new Number(3);
typeof new Boolean(false);

Then they’ll all return type 'object' even though we work with them as we do with their primitive counterpart.

To convert them back to primitive values, we’ve to call the valueOf method on them as follows:

new String("foo").valueOf();
new Number(3).valueOf();
new Boolean(false).valueOf();

to get back the primitive version of those wrapper objects.

We should instead write them out as primitive value literals as follows:


It’s less typing and there’s no confusion about the types.

No Octal Literals

Octal number literals are any numbers that start with a 0. JavaScript treats anything that starts with a 0 as an octal number.

Therefore, 051 is actually 41 in decimal.

This is a source of confusion, so octal numeric literals are deprecated in ES5.

Therefore, if we want to write 51 in our code, then we shouldn’t have a 0 before it.

No Reassignment of Function Parameters

We shouldn’t reassign function parameters to a different value in JavaScript because it’ll mutate the arguments object. This means that the actual parameters are modified.

It’s easy to make mistakes by reassigning function parameters to a new value. And it makes errors hard to track down.

For instance, we should write code like:

const foo = (x) => {
  x = 13;

const foo = (x) => {
  for (x of baz) {}

Instead, we should assign the parameter to a variable inside the function body and then manipulate it as we do in the following code:

const foo = (x) => {
  let y = x;

const foo = (x) => {
  for (const b of baz) {}

Don’t Use the __proto__ Property to Access the Prototype of the Given Object

We shouldn’t use the __proto__ property to access the prototype of the object that we’re trying to access this property on.

Instead, we can use the Object.getPrototypeOf method to access the prototype of the current object.

For instance, instead of writing:

const obj = {};

We should write:

const obj = {};

No Variable Redeclaration

Redeclaring variables are bad. However, it’s possible to do this if we use the var keyword to declare our variables. We don’t want that to happen because we don’t which value our variable actually has.

For instance, if we have:

var a = 3;
var a = 2;

Then we get that a is 2 when we log a below the last line.

Instead, we should declare a variable with let , then we would get an error is we try to declare 2 variables with 2 different names.

Photo by Kae Ng on Unsplash

No Assignment in return Statement

In JavaScript, we can do an assignment operation in the same line as the return statement.

For instance, we can write something like:

const baz = (bar) => {
  return foo = bar + 2;

In the code above, we have the bar parameter and we add 2 to it. Then we assigned the sum to foo and then returned it.

Therefore foo is 5 and we returned that. However, it might also be a typo because the developer may mean to write == or === instead of = .

To make things clearer, we should put an assignment expression on a different line than the return statement.

We can also put parentheses around the assignment expression to make everyone clear that we’re assigning the value to the left operand first and then returning the left operand as the value.

So we can write:

const baz = (bar) => {
  return foo == bar + 2;

const baz = (bar) => {
  return foo === bar + 2;

const baz = (bar) => {
  return (foo = bar + 2);

instead of what we have above.


We shouldn’t use wrapper objects for primitive values since there’s no value to creating them manually. It only brings confusion to other developers and requires more typing.

Also, we shouldn’t have octal literals in our JavaScript code since they’ve deprecated.

We shouldn’t declare variables with the same name more than once.

Finally, assignment expressions shouldn’t be in return statements to reduce chance ambiguity.

JavaScript Mistakes

JavaScript Mistakes — Clumsy and Useless Expressions

JavaScript is a very forgiving language. It’s easy to write code that runs but has mistakes in it.

In this article, we’ll look at some clumsy or useless expressions that shouldn’t be in our JavaScript code including useless blocks, magic numbers, multiline strings, and spaces, and using new without assigning the returned object.

Unnecessary Nested Blocks

Since ES2015, we can define blocks to segregate our code. They’re denoted by curly braces.

It’s useful for segregating block-scoped variables that are declared with let or const or class declarations or function declarations that are declared in strict mode,

However, we should add blocks unnecessarily. For instance, the following is useless:

  function foo() {}

We should never put function declarations in blocks. It’s not allowed in JavaScript since they’re only allowed at the top-level.

What we should do is put function declarations at the top level as follows:

function foo() {}

We should place variables and constants that are declared with let and const in a block, as follows:

  let x = 1;
  const y = 2;

In the code above, we put x and y in blocks. This way, they can only be accessed inside a block.

No Magic Numbers

Magic numbers are numbers that occur multiple times in our code without any explicit meaning. They should be named constants to make them clear what they mean and that we can reference the constant in multiple places.

This way, we only have to change the value once if we need to change it instead of making changes in multiple places.

For instance, instead of writing:

let x = 1;
let y = 1;
let z = 1;

We can move the 1’s into one constant as follows:

const numPerson = 1;
let x = numPerson;
let y = numPerson;
let z = numPerson;

This way, we know that 1 is the number of persons, and we can also reuse it in multiple places and only change it in one place if we need to change it.

No Multiple Spaces

Multiple spaces are confusing and they aren’t very clean. For instance instead of writing:

if(foo  === "baz") {}

We should instead write:

if(foo === "baz") {}

However, we can put comments after multiple spaces after the end of the line. For instance, the following:

if(foo === "baz") {}    // check if foo is 'baz'

If it makes comments line up better, then it’s OK for comments to come after multiple spaces after a piece of code.

No Multiline Strings

If we want to write strings with multiple lines before we had template strings, we have to write something like the following:

let x = "foo

In the code above, we put 'bar' on a new line with a “ . It’s an undocumented feature of JavaScript and now that we have template strings, we shouldn’t use this.

Instead, we should use template strings as follows:

let x = `foo

or we can write:

let x = 'foonbar'

Template strings preserve all whitespaces so we have to be precise with the spaces,

The n character also creates a new line.

Photo by Dan Gold on Unsplash

Don’t Use the new Operator Without Assigning the Returned Object

The new operator is used for creating a new instance of a constructor. Therefore, we should always assign it to something.

Using new without assigning the returned result to anything is dubious because either it achieves nothing, or we’re using it to commit side effects.

Constructors aren’t a good place to commit side effects since most people expect it to return an instance of the constructor.

Therefore, we shouldn’t use the new operator without assigning the returned value to the variable or constant of our choice.

For instance, instead of writing:

new  Foo();

We should write:

const foo = new Foo();

Don’t use the Function Constructor

The Function constructor is bad. We pass in strings for specifying the parameters and the function body. The last argument is the body while the arguments before it are the parameters.

They’re hard to debug since they’re all strings. Because they’re all strings, they’re also hard to read.

In addition, if they’re dynamic, then attackers can inject their own code and create their own functions and run malicious code.

Therefore, we should avoid using the Function constructor at all costs. Instead of writing:

const add = new Function("a", "b", "return a + b");

We should write:

const add = (a, b) => a + b;

This way, they’re clean and easy to debug.


Useless blocks, extra spaces, multiline strings that aren’t standard should all be avoided.

Magic numbers should be assigned as constants so they can be understood and reused.

Anything returned with new should be assigned to a variable or constant.

Also, we should never use the Function constructor to make our code easy to read and debug and let us avoid potential security issues.

JavaScript Mistakes

JavaScript Mistakes — Things We Shouldn’t Put into Our Code

JavaScript is a very forgiving language. It’s easy to write code that runs but has mistakes in it.

In this article, we’ll look at things that we shouldn’t be putting in our code.

We Shouldn’t Put Assignment Operators in Conditional Statements

We shouldn’t put assignment operators in conditional assignments. For example, the following is probably a mistake:

if (title = "manager") {


The code above sets the title to 'manager' instead of checking if title has the value 'manager' . It’s probably a mistake since most people want to check the value with the === operator rather than doing an assignment operation in the if statement.

What we actually want is:

if (title === "manager") {


We Shouldn’t Leave Console in Production Code

console.log and other console methods are very useful for debugging our code. However, before we put them into production, we should have them removed so we aren’t exposing anything to the user unintentionally.

Therefore, the following code shouldn’t be in production code:


Other console method calls also shouldn’t be committed. The only exception to this is when we use console to output data to the user in Node.js apps.

Then we may want to ignore this rule.

We Shouldn’t Put Constant Expressions in Conditions

Constant expressions are most likely a mistake unless we’re doing it intentionally. For instance:

if (false) {

The code above never runs since the condition inside is always false .

Also, when constant conditions are used in loops, we may get infinite loops or loops that never run. For example, the following is an infinite loop:

while (true) {

We probably don’t want that in most cases. If the condition in ternary expressions is constant, then it’s pretty useless since it always returns one value.

For instance:

let result = true ? 'foo' : 'bar';

Then result is always 'foo' since the condition is true , so the first value will always be returned.

Examples of code that make more sense include:

while (true) {
  if (conditionFalse()){

Putting Control Characters in JavaScript Regular Expressions

Control characters are in ASCII range 0 to 31. They’re special, invisible characters. These characters are rarely used in JavaScript strings so it’s probably a mistake.

For instance, the following is probably not what we want:

`const pattern1 =` /\x00/;
`const pattern2 = new RegExp("\x00");`

It’s very rare that we want to match the null character, which is character 0 in ASCII.

We Shouldn’t Put debugger Statements in Production Code

As its name suggests, debugger is used for debugging. It pauses the program in that line so that we can inspect the items in the current point in the code.

Also, there’re better ways to debug code that with debugger . Production code definitely shouldn’t have debugger in it because it pauses the program that the user is using if it’s present.

For instance, the following is a mistake:

const isTrue = (x) => {
  return x === true;

In production code, we should write:

const isTrue = (x) => {
  return x === true;

Photo by Sebastian Herrmann on Unsplash

We Should Never have Duplicate Arguments in Functions

Having the multiple parameters with the same means that the last occurrence of the parameter taking on the value of the last parameter with the same name.

For example, if we have:

const foo = (a, b, a) => {

Then when we call foo as follows:

foo(1, 2, 3);

We see the value 3 logged. This causes confusion and it’s probably a mistake. It doesn’t make much sense to have 2 parameters with the same name.

Instead, we should rename the 3rd parameter:

const foo = (a, b, c) => {

or remove the second a :

const foo = (a, b) => {


There’re many kinds of mistakes that can be made when writing JavaScript code because of its forgiving nature. We should never leave debugging code like console or debugger . The only exception is when we use console to output values to users in Node apps.

Constant expressions in conditions are most likely to be mistaken. In conditional statements, we write code that always runs or never runs.

If they’re in loops, then they either create an infinite loop or one that never runs.

In ternary expressions, we create one that always assigns the same value. Therefore, it’s most likely not very useful and it’s a mistake.

Finally, we shouldn’t have duplicate parameter names in functions. It causes confusion since the last value that’s passed in overwrites the first one that’s assigned to the same parameter name.