Categories
JavaScript Best Practices

JavaScript Best Practices — Declaring and Using Variables

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

In this article, we’ll look at best practices for declaring and using JavaScript variables.

Implicit Declarations

In JavaScript, if strict mode is off, then we can implicitly declare variables. We can reference variables without declaring it if it’s off, which isn’t good.

For instance, we can write:

foo = 1;

with strict mode off. This will declare a global variable foo , which can be accessed anywhere.

This isn’t good since it’s declared without using doing it and it’s global.

So we should turn on the strict mode in scripts as it’s a hazardous feature to use.

Declare All Variables with let or const

We should always declare all variables with let or const .

Use let for variables and const for constants.

const constants can’t be reassigned to a new value after it’s declared and we must set a value when we declare it.

For instance, we can write:

let x = 1;  
const y = 2;

We can also write:

let x;

Use Naming Conventions

Naming conventions for common suffixes o that we don’t use variables when only need one.

If we use Num as a suffix, then stick with that for numbers, for example.

Check Variable Names

We should check variables as they’re listed in editors and IDEs. Then we can remove variables that aren’t used.

Guidelines for Initializing Variables

Improper data initialization is a big source of problems in computer programs.

If we initialize them properly, we can save lots of debugging time.

If a variable has never been assigned a value, then we should assign one.

If it has an outdated value, then we need to update it.

If part of it has been assigned and another part isn’t then we need to set that part.

We can do that by setting properties or adding to arrays.

Initialize Each Variable as it’s Declared

We don’t have to set a value for let variables when we declare them, but we should set it since we’ll probably forget later.

Also, they should be near where they’re used since we may forget to use them if we don’t.

It also creates the impression that the variable is used throughout the code, which isn’t desirable.

Ideally, Declare and Define Each Variable Close to Where it’s First Used

This make us only declare variables when they’re needed.

It also let people know that the variable isn’t used throughout the code.

Photo by Tim Cooper on Unsplash

Use const When Possible

If we use const , then we can’t assign it to a new value.

However, we can still mutate the object inside.

Pay Special Attention to Counters and Accumulators

If we have counters and accumulators, then we should remember to reset them before they’re used again if necessary.

Initialize a Class’s Member Data in its Constructor

We should initialize all class’s instance variables in the constructor so that they’re ready to use anywhere.

For instance, we can write:

class Person {  
  constructor(name, age) {  
    this.name = name;  
    this.age = age;  
  }  
}

This makes this.name and this.age defined in all methods in the class.

Check the need for Reinitialization

If the value of a variable needs to be initialized, then we should use let . Otherwise, we use const .

Initialize Named Constants Once; Initialize Variables with Executable Code

We should declare named constants with const so that they can’t be reassigned to a new value.

If we have variables, they should be declared with let or const before the code that uses it in a function so that we can reinitialize it as the function is called.

Use Linter Setting that Automatically Initializes All Variables

We can use a linter to check that all variables are initialized.

This makes the process automatic so that we can avoid errors.

Take Advantage of Our Linter’s Warning Messages

Linters like ESLint has lots of rules that we can check to make sure that we’re declaring variables properly.

Therefore, we should take advantage of them so that we can fix improper variable declarations automatically when detected.

Conclusion

We should declare variables properly. It’s easy to do with a linter.

Implicit declarations are bad as they’re global. And we should use let and const to declare them instead.

Strict mode prevents implicit variable declarations.

Categories
JavaScript Best Practices

JavaScript Best Practices for Writing More Robust Code — Finding Items

JavaScript is an easy to learn programming language. It’s easy to write programs that run and does something. However, it’s hard to account for all the uses cases and write robust JavaScript code.

In this article, we’ll look at more reliable ways to filter and check for items in arrays.

Check to See If Something Exists in All Entries of an Array With the every Method

The JavaScript array instance’s every method lets us easily check if something exists in all entries of an array.

All we have to do is to pass in a callback with the condition we want to check for in each entry.

For instance, if we want to check if every number in the array is even, we can write the following code:

const arr = [2, 4, 6];
const allEven = arr.every(a => a % 2 === 0);

In the code above, we have the arr array with all even numbers. Then we used every that has a callback with the array entry a as the parameter and we return a % 2 === 0 to check if all numbers in the array are even.

Since they’re all even, allEven is true as every returns true if every entry in the array instance meets the condition given in the callback and false otherwise.

This is more reliable than writing our own loops since it’s shorter and well-tested. Therefore, there’s less chance for bugs.

The callback can also take other parameters. The index that’s being looped through is the 2nd parameter and the array itself if the third. They’re both optional. However, if we need it, then we can include them.

For instance, we can rewrite our example as follows:

const arr = [2, 4, 6];
const allEven = arr.every((a, index, array) => array[index] % 2 === 0);

The every method also takes an object that we can set as the value of this in the callback, if we need to reference this in the callback function.

For instance, we can write the following code to set the value of this and use it inside the callback:

const arr = [1, 2, 3];
const allEven = arr.every(function(a){
 return a >= this.min;
}, { min: 2 });

In the code above, we set the value of this in the callback by passing in { min: 2 } as the 2nd argument.

Then we switched our function into a traditional function so that we can reference the this value in the callback. In the callback, we checked that if each array entry is bigger than or equal than this.min , which is 2.

We don’t have to worry about how to set up our loops and when to end the loop and other things that come with the loop.

Creating an Array With Filtered Entries With the filter Method

The array instance’s filter method returns an array with the entries of an array that has the given condition in the callback included the returned array.

For instance, we can use it as follows:

const arr = [1, 2, 3];
const result = arr.filter(a => a > 1);

In the code above, we called filter on the array instance with the callback a => a > 1 to return a new array with all the entries in arr that’s bigger than 1.

Therefore, we should get [2, 3] as the value of result .

Like every , the callback can also take an optional index and array parameter. index is the 2nd parameter, and array is the 3rd parameter.

So we can also write the following code:

const arr = [1, 2, 3];
const result = arr.filter((a, index, array) => array[index] > 1);

In the code above, we used the array and index instead to reference the entries and instead of using the first parameter a to reference each entry.

Therefore, we should get the same result as before.

This is better than writing our loops since it comes with JavaScript’s standard library, so it’s been well tested to eliminate any bugs.

Also, the algorithm it uses for doing the filtering is guaranteed to be fast enough for production use since it’s in the standard library.

Finally, it’s also shorter than writing our own loops to do the same thing.

Conclusion

The array instance’s every method is great for checking is every entry has something we’re looking for.

To create a new array with the entries in the array instance that meets the given condition, we can use the array instance’s filter method to make that easy.

Categories
JavaScript Best Practices

JavaScript Best Practices — Variables

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 best ways to define and use variables in our JavaScript code.

Always Use const or let to Declare Variables

We should use let and const to declare variables and constants respectively.

This way, we get block-scoped variables and constants so we won’t run into issues with variables or constants being accessed in places that we won’t expect.

Without strict mode on, using let and const will also stop us from creating global variables.

Global variables pollute the global namespace and the more complex our code is, the more likely that our global variables will have the same name in different places. Then unexpected behavior will occur because of that.

const also prevents us from the reassignment of its value after it’s set. Both let and const prevents us from declaring a variable with the same name twice.

For instance, we can declare variables and constants with let and const as follows:

let a = 1;
const b = 2;

In the code above, we declared a variable a with let and a constant b .

Then we don’t have to worry about them being declared somewhere else or in the case of b , its value being reassigned to something else.

Use One const or let declaration Per Variable or Assignment

We should put each of our let and const declarations in their own line.

For instance, instead of writing the following code to declare multiple variables in one line:

const a = 1,
  b = 2,
  c = 3;

We should instead put the const keyword in front of every declaration as follows:

const a = 1;
const b = 2;
const c = 3;

This way, we know that every line in the code above is declared with const . In the first example, we aren’t sure how they’re declared.

Also, it’s easier to swap variables that are in their own line since we can cut or copy and paste the whole line.

We can also step through each line with the debugger instead of looking at all the declarations at once.

Group All consts Declarations Together and Then Group All let Declarations Together

We should group all the const declarations together and then group all the let declarations together.

If we scatter them everywhere, then we’ll have a problem finding them later.

Also, we might need to assign a variable depending on one of the previously assigned variables.

For instance, if we have the following code:

const a = 1;
let foo;
const b = 2;
let bar;
const c = 3;

Then it’s hard to read and trace which variable is assigned to what. Instead, we should write the following:

const a = 1;
const b = 2;
const c = 3;

let foo;
let bar;

which is much more organized.

Photo by John Duncan on Unsplash

Assign Variables Where We Need Them But Place Them in a Reasonable Place

We should assign variables where we need since let and const variables are block-scoped and what those are the variables and constants that we should have.

Variables declared with var are function scoped and are hoisted so they can be accessed in places that we may not expect them to be accessed.

For instance, we should place our variables as follows:

const getGreeting = () => 'hi';

const greet = (name) => {
  if (!name) {
    return '';
  }

  const greeting = getGreeting();
  return `${greeting} ${name}`;
}

In the code above, we have the greeting constant inside our greet function. We put it there so we don’t have to run the getGreeting function unnecessarily.

We only run the getGreeting function when the name is a truthy value so that we don’t have to run it on every call.

Therefore, we didn’t place the code for the greeting declaration at the top line of or greet function as follows:

const getGreeting = () => 'hi';

const greet = (name) => {
  const greeting = getGreeting();
  if (!name) {
    return '';
  }

  return `${greeting} ${name}`;
}

It’s more efficient to declare variables and constants only when we need to use them.

Conclusion

When we declare variables, we should always use let or const to only declare block-scoped variables and constants.

const and let variables should be grouped in their own group. Also, they should be declared only when they’re needed.

Categories
JavaScript Best Practices

JavaScript Best Practices for Writing More Robust Code — Variables and Objects

JavaScript is an easy to learn programming language. It’s easy to write programs that run and does something. However, it’s hard to account for all the uses cases and write robust JavaScript code.

In this article, we’ll look at what JavaScript features should be used to write our JavaScript apps.

Writing Blocked-Scoped Code

Keeping all our code in blocks and variables inside it within the block’s scope is important because it reduces lots of confusion when people are reading code.

If everything is block-scoped, then we know that everything inside a block can only be accessed within the block. Therefore, it’s impossible for anyone to assign values to a block-scoped variable outside the block.

This means that we should never use var , we should always use strict mode, and we should always use let and const to declare variables and constants respectively.

let and const are both block-scoped, so that they’re only available in the block that they’re declared in.

For instance, we can create a code block with let and const variables and constants as follows:

if (foo){
 let x = 1;
}

In the code above, we have an if block with the variable declaration for x inside it.

When we try to reference it anywhere outside the if block, we’ll get an error since it’s not accessible outside the block. This rule never changes.

Unlike variables declared with var , there’s no hoisting, and it can’t be accessed outside the block.

var variables are accessible within the entire function, which is probably not what we want as it creates confusion on where we can reference it. Therefore, we shouldn’t use it.

Since ES2015, we can also define standalone code blocks in addition to if , switch , and functions.

This also limits the access of our variables and constants to that block if we use let and const to declare the variables and constants respectively.

For instance, we can do that as follows:

{
  let x = 1;
  const y = 2;
}

In the code above, we defined a block and then declared the x variable and y constant.

They can only be referenced inside the curly braces. This is much better than declaring a function and running it immediately since it’s less typing and we don’t have to declare another function unnecessarily.

const is different from let in that we can’t reassign something that’s declared with const . However, we can still modify the assigned object if we wish.

The Spread Operator

The spread operator, which is denoted by 3 periods, spreads array entries and object values to another array or object respectively.

This lets us create objects and arrays by merging one or more of them together.

We can also spread arrays into objects, which creates an object with the indexes of the original array as the keys and the corresponding entries as the values.

This is a quick and easy to understand method to merge multiple objects or arrays or make copies of them without writing any loops or anything more complex.

For instance, we can spread and object as follows:

const arr = [1, 2]
const obj = {
  ...arr
};

Then we get:

{
  "0": 1,
  "1": 2
}

as the value of obj as we expected.

Also, we can make a copy of an object as follows:

const obj = {
  a: 1
};
const copy = {
  ...obj
};

In the code above, we used the spread operator to make a shallow copy of obj by using the spread operator to spread the entries into the copy object.

Then we should see the same keys and values in both constants, but when we log obj === copy , we’ll see that the expression returns false since the spread operator creates a copy instead of referencing the original object.

The spread operator is also very handy for merging objects and arrays into one.

For objects, we can write the following to combine multiple object’s own properties into one object as follows:

const obj1 = {
  a: 1
};
const obj2 = {
  b: 2,
  a: 3
};
const merged = {
  ...obj1,
  ...obj2
}

In the code above, we merged obj1 and obj2 into a new object called merged using the spread operator. If 2 keys are the same, then the one that’s merged in later is kept.

Therefore, we see that merged is:

{
  "a": 3,
  "b": 2
}

We can also use that with arrays. All entries of the original array are kept. For instance, we can write:

const arr1 = [1, 2]
const arr2 = [3, 4, 5]
const merged = [...arr1, ...arr2]

Then merged is:

[
  1,
  2,
  3,
  4,
  5
]

The spread operator is a short, less error-prone, and easy to understand method to copy and merge objects and arrays, so it should be used for such purpose instead of writing anything more complex.

Conclusion

Some of the best JavaScript features that are released in the last few years are block-scoped variables and constants and the spread operator.

Block-scoped variables and constants reduces the chance of error by creating variables and constants that are always block-scoped, so it’s harder for values to be changed unintentionally.

The spread operator lets us copy and merge objects and arrays in a more reliable way.

Categories
JavaScript Best Practices

JavaScript Best Practices for Writing More Robust Code — Good and Bad Features

JavaScript is an easy to learn programming language. It’s easy to write programs that run and does something. However, it’s hard to account for all the uses cases and write robust JavaScript code.

In this article, we’ll look at some good features of JavaScript that we should use to write robust JavaScript code.

Use === Instead of ==

In JavaScript, there’s the === and == operators for determining the equality of 2 entities.

== coerces the type by following a long list of rules before doing the comparison between its 2 operands.

On the other hand, === doesn’t do any data type coercion before comparing its operands.

This makes === better since JavaScript’s data type coercion creates weird results that we don’t expect.

Using the == operator leads to expressions like 0 == false returning true .

We don’t want to make things a lot harder by saving one character on our code, so we should always use === to do equality comparisons.

Likewise, to check for inequality, we should use the !== operator, which also doesn’t do any data type coercion before comparing its operands for inequality.

Never Use Eval

eval lets us run code that’s embedded in a string. This means that theoretically, any user can run anything as long as they can set the value of the string that we pass into eval .

The code in eval runs in global scope so it can have a big impact if we let anything run with eval .

Therefore, we should avoid this at all costs. Also, it decreases our app’s performance since running code from a string means that the JavaScript interpreter can’t do any performance optimizations beforehand.

Never Use the Function Constructor

The Function constructor is like eval . It lets us define a function by passing in the code that we want to run inside the function.

For instance, we can pass in the parameter names and the function body as strings by writing the following:

const add = new Function('x', 'y', 'return x + y');

In the code above, we invoked the Function constructor with the 'x' and 'y' strings, which are the parameter names. Then we have 'return x + y' as the 3rd argument to return the sum of x and y .

We can then run our function as follows:

const sum = add(1, 2);

Like eval , we dynamically pass in strings to write our code. It also runs everything in the global scope and prevents optimizations just like eval does.

It also has the same security issues as eval since we still pass in strings to define our functions.

Therefore, we also shouldn’t use this to define our functions.

Don’t Pass in Strings as Code in setTimeout and setInterval

The setTimeout and setInterval functions allow us to run code after a delay and run code in a specified interval respectively.

One feature we shouldn’t use in either of them is passing strings into them to run code.

For instance, we shouldn’t write something like the following:

setTimeout('console.log("foo")', 100)

This will run console.log("foo") after 100 milliseconds, but we shouldn’t do this since again, we’re running code from a string which presents the same security and performance issues as the other occasions where we run code from a string.

Therefore, we should always run code that’s defined with code instead of a string, like the following:

setTimeout(() => console.log("foo"), 100)

The code above runs console.log like it does with the string, but the JavaScript interpreter can optimize the code and there’re no security issues since there’s no risk that attackers can inject code into our app as a string.

Always Add Semicolons and Parentheses

Semicolons should always be added to make our code as clear as possible. JavaScript can insert semicolons automatically when we don’t do it ourselves. Parentheses can also be optional with one-line if blocks.

It’ll insert it when it thinks it should be a new line, like in any logical break that it finds.

However, it often leads to confusion. If we write something like the following:

if (foo)  
  x = false  
  bar();

Then we may think that both lines are run if foo is true . But this isn’t the case.

The JavaScript interpreter will think that only x = false is part of the if block and bar() is separate.

Therefore, if we want to eliminate confusing code like this, we should write:

if (foo) {  
  x = false;  
  bar();  
}

to delimit our lines and blocks with semicolons and parentheses.

This way, we know that they both will run if foo is true .

Conclusion

=== and !== are always better than == and != for equality and inequality comparisons respectively.

Also, we should never run code from a string with eval , the Function constructor, setTimeout , setInterval or any other place that allows us to do that.

Finally, we should add semicolons and parentheses to delimit our code blocks.