Effective JavaScript - 10 JavaScript Concepts You Should Know

Love it or hate it, JavaScript is indeed a very peculiar language. Learning JavaScript can cause a lot of headaches, especially for those coming from another programming environment.

Nonetheless, JavaScript is a top programming language, and if you’ve decided to learn it, there are quite a few things to be aware of. This article is going to explore some of the peculiarities of JavaScript as well as a few other things you should know about. By the end of the article, you should have a better awareness of JavaScript’s idiosyncrasies, enabling you to write better code and avoid errors in production.

Item 1: Floating-Point Numbers

Most programming languages have a few diferent types of numeric data values. JavaScript has just one: number.

typeof 10; // 'number'
typeof 10.5; // 'number'

What happens when we deal with floating point numbers in JavaScript? They can be quite frightening.

Question: what does 0.1 + 0.2 equal? 0.3!

Well let’s enter it into a JavaScript console for a surprise:

console.log(0.1 + 0.2); // 0.30000000000000004

Yikes! What happened? It’s a bit complex, but all numbers in JavaScript are double-precision floating-point numbers (i.e. the 64-bit encoding of numbers specified by the IEEE 754 standard, commonly known as “doubles”).

Does this make you nervous? It should. We are too. Do keep this in mind if you ever find yourself dealing with financial applications.

// Enter this in your browser console to learn more about floating-point numbers
window.location = `https://${0.1 + 0.2}.com`;

Item 2: Type Coercion

Type coercion is the implicit conversion of values from one data type to another. Let’s take a look at an example.

const a = "2";
const b = 3;
let sum = a + b;

console.log(sum); // 23

a is of type string. b is of type number. In many programming languages, you would not be able to add these two values together, you’d receive a TypeError message explaining that you cannot add an int and a str together.

So what happened? The JavaScript interpreter coerced the 3 from a number and then concatenated the two values together, returning a string of 23.

Along with being a loosely typed language, this sort of behavior brings a lot of criticism to JavaScript.

Item 3: Lexical Environment

Lexical environment determines where variables work and where they don’t, based on where they’re defined within our code.

Let’s explore the different types of scope.

  • Global scopevariable is available everywhere.
  • Local scopevariable defined in a function, only available within that function.
  • Block scope - variable is defined within curly braces within our function.
Global Scope

This variable is defined at the top of our file, and is available throughout or code.

// Global scope
let a = "global";
Local Scope

This variable is defined within a function block, and is available only within that function.

// Local scope
function scope() {
  let a = "local";
  console.log(a); // local
}

scope();

console.log(a); // ReferenceError: a is not defined
Block Scope

This variable is defined within an if statement within our function, and is only available within that block (i.e. the curly braces of the if statment).

// Block scope
function scope() {
  let a = "local";

  if (true) {
    let b = "block";
  }
  console.log(b);
}

scope(); // ReferenceError: b is not defined

Item 4: Variable Hoisting

Extending on item 7, let’s take a look at variable hoisting. Hoisting is a side-effect of using the var keyword.

function scope() {
  let a = "local";

  if (true) {
    let b = "block";
    var c = "Hello";
  }
  console.log(c);
}

scope(); // Hello

What happened? We just tried this above, with let b = 'block', which resulted in an ReferenceError. Simply put, the var keyword was hoisted up into the local scope of the function. By ‘hoisted’, we mean the variable was moved pre-execution of the code.

Do be aware of this side-effect. It is generally recommended to avoid using the var keyword altogether.

variable hoisting javascript

From MDN, the following behaviors may be regarded as hoisting:

  1. Being able to use a variable’s value in its scope before the line it is declared. (“Value hoisting”)
  2. Being able to reference a variable in its scope before the line it is declared, without throwing a ReferenceError, but the value is always undefined. (“Declaration hoisting”)
  3. The declaration of the variable causes behavior changes in its scope before the line in which it is declared.

Item 5: The this Keyword

The this keyword tends to cause a lot of confusion among beginner programmers learning JavaScript. this is a keyword that represents an object based on how a function is called. When this is called from the global scope, it references the window object (global/window) in the browser.

function thisExample() {
  console.log(this);
}

thisExample(); // Object [global] { ... };

However, if that function is attached to an object and called by that object, this will be a reference to that object.

const thisExample = {
  thisObj: function () {
    console.log(this);
  },
};

console.log(thisExample); // { thisObj: [Function: thisObj] }

Item 6: Event Loop

JavaScript’s runtime is based on an event loop, which is responsible for executing code, collecting and processing events, and executing queued sub-tasks. The event loop is non-blocking, which allows us to write asynchronous code.

If it weren’t for the non-blocking nature of JavaScript, code would need to be executed line-by-line, blocking the event loop, resulting in slow performance and frequent crashes. This is known as synchronous code.

JavaScript is single-threaded. Without asynchronous code, multiple tasks would not be able to be performed.

Let’s take a look at an example:

setTimeout(() => {
  console.log("3 seconds later...");
}, 3000);

setTimeout takes a function as an argument, but won’t call that function until a specified amount of time (in our case, 3 milliseconds). The callback function within setTimeout gets enqueued in the event loop only to be called back later when it’s ready to be executed on the main thread.

Learn more about the event loop.

Item 7: Callbacks

A callback function is a function that is passed into another function as an argument.

function multiply(x, y) {
  return x * y;
}

function calculate(callback) {
  return callback(2, 2);
}

console.log(calculate(multiply));

In the above code, the callback function is multiply(), as it is the function being passed into calculate() as an argument. Our example uses synchronous code, it is executed immediately.

Please note that callbacks are often used to continue code execution after an asynchronous operation has completed (e.g. downloading things, reading files, talking to databases, etc.).

Item 8: Promise

Promises are the building blocks of asynchronous operations in modern JavaScript. Essentially, a promise is an object representing the eventual completion or failure of an asynchronous operation – which will either be resolved (completion) or rejected (failure).

When a Promise is resolved or rejected, we can attach two methods to continue the code execution:

  • .then() - Takes up to two arguments. The first is executed when the Promise is resolved and the result received. The second (optional) argument is to be used in case of failure.
  • .catch() - Will be used as an error handler, being called if the Promise fails.

Example of a Promise with .then():

const promise = new Promise((resolve, reject) => {
  resolve("Success!");
});

promise.then((value) => {
  console.log(value); // "Success!"
});

Example of a Promise throwing an error with .catch():

const promise = new Promise((resolve, reject) => {
  resolve("Success!");
});

promise
  .then((value) => {
    throw new Error("oh no!");
  })
  .catch((err) => console.log(`Rejected! ${err.message}`)); // Error: oh no!

Item 9: IIFE (Immediately-Invoked Function Expression)

An IIFE (Immediately-Invoked Function Expression) is a function that is executed as soon as it’s defined.

(function greet() {
  console.log("Hello!");
})();

If you run the code above, you’ll see Hello! printed to the console immediately. No function call was necessary to execute the code, hence immediately invoked.

From Wikipedia: IIFEs can be used to avoid variable hoisting from within blocks, protect against polluting the global environment and allow public access to methods while retaining privacy for variables defined within the function.

Item 10: Beware of Semicolon Insertions

You might have noticed that some JavaScript developers omit the use of semicolons. It can be quite convenient for those who also work with Python.

However, you might be confused by this. How does this work? Is there anything to be aware of?

This works thanks to automatic semicolon insertions – a parsing technique that effectively inserts the semicolon into the program for you.

To answer the second question, yes, there are a few things to be aware of:

  1. Semicolons are only inserted before a }
  2. After one or more newlines
  3. At the end of the program input

Conclusion

Well, that wraps up the list. We hope you enjoyed these 10 JavaScript concepts and learned some things while reading this article!

This article will eventually be expanded, so feel free to bookmark this page and return at a later time.

If you still feel like reading, feel free to explore our homepage, and check out our other articles. Also, feel free to comment below with any questions or comments below!

Explore Udacity’s Intermediate JavaScript Nanodegree program and save an additional 40% when you pay upfront with code CAREER22! By using this link, we will make a small commission at no extra cost to you. Thank you for the support!

comments powered by Disqus

Related Posts

Security & Cyber Crime Blogs You Should Be Reading

Digital threats are plenty and cyber attacks are a constant concern. As developers, we should be aware of the threats our software may encounter as we develop applications.

Read more

Learning Programming for Free in 2024: 6 Websites to Check Out

In the modern world, people can switch careers several times during a lifetime. And going for an IT-related profession, for example, becoming a software developer, makes a lot of sense.

Read more

Routing with Angular: A Quick Tutorial

Today, we’ll be looking at the navigation and routing aspects in Angular. This tutorial is a continuation of our previous starter tutorial where we created a simple Angular application, installed Tailwind CSS, and created a navigation bar.

Read more