DEV Community

Cover image for The Main and Tricky Concepts in JavaScript
Renuka Nandikolla
Renuka Nandikolla

Posted on

The Main and Tricky Concepts in JavaScript

1.scopes

2.Hoisting

3.Functions

4.Arrow Functions

5.Promises

6.Fetching API

7.Async/Await


1. Scopes 🌎

Scope determines the accessibility of variables in JavaScript.

Types of Scope

  • Global Scope 🌍: Variables declared outside any function are accessible everywhere.
  • Local Scope πŸ”’: Variables declared inside a function are only accessible within that function.
  • Block Scope 🧱: Introduced with let and const, variables declared inside {} cannot be accessed outside.
  • Function Scope 🎯: Variables declared using var inside a function are only accessible within that function.

2. Hoisting πŸš€

Hoisting is JavaScript’s behavior of moving variable and function declarations to the top of their scope before execution.

Example

console.log(a); // undefined (not error)
var a = 10;

foo(); // βœ… Works! Function declarations are hoisted
function foo() {
    console.log("Function Hoisted!");
}

// Function Expressions are **not** hoisted
bar(); // ❌ Error: bar is not a function
var bar = function () {
    console.log("Function Expression");
};
Enter fullscreen mode Exit fullscreen mode

Note: Only function declarations are fully hoisted, but variables declared with var are hoisted with undefined value.


3. Functions 🎭

Function Declaration vs Function Expression

Feature Function Declaration Function Expression
Hoisted? βœ… Yes ❌ No
Can be called before declaration? βœ… Yes ❌ No
Syntax function func() {} const func = function() {}

Example

// Function Declaration
function greet() {
    return "Hello!";
}
console.log(greet()); // βœ… Works!

// Function Expression
const greetExpression = function() {
    return "Hello from expression!";
};
console.log(greetExpression()); // βœ… Works only after definition
Enter fullscreen mode Exit fullscreen mode

4. Arrow Functions ➑️

Arrow functions provide a more concise syntax for writing functions.

Syntax

const functionName = (parameters) => expression;
Enter fullscreen mode Exit fullscreen mode

Example

// Traditional Function
function add(a, b) {
    return a + b;
}

// Arrow Function Equivalent
const addArrow = (a, b) => a + b;

console.log(addArrow(3, 4)); // Output: 7
Enter fullscreen mode Exit fullscreen mode

Key Differences

  • this is lexically bound (inherits from the surrounding scope).
  • Cannot be used as constructors (new keyword).
  • No arguments object available.

5. Promises 🀝

A Promise is an object that represents the eventual completion or failure of an asynchronous operation.

States of a Promise

  1. Pending 🟑 - Initial state, before the result is available.
  2. Fulfilled βœ… - The operation was successful.
  3. Rejected ❌ - The operation failed.

Why use Promises?

βœ”οΈ Handle asynchronous operations efficiently.

βœ”οΈ Avoid callback hell.

Example

const myPromise = new Promise((resolve, reject) => {
    let success = true;
    setTimeout(() => {
        if (success) resolve("Promise resolved! βœ…");
        else reject("Promise rejected! ❌");
    }, 2000);
});

myPromise
    .then(response => console.log(response))  // Runs if resolved
    .catch(error => console.log(error));      // Runs if rejected
Enter fullscreen mode Exit fullscreen mode

6. Fetching Data from an API 🌍

Fetch is used to request data from a server.

Example

fetch("https://jsonplaceholder.typicode.com/posts/1")
    .then(response => response.json()) // Convert response to JSON
    .then(data => console.log(data))   // Log data
    .catch(error => console.log("Error:", error));
Enter fullscreen mode Exit fullscreen mode

It returns a Promise, which we handle using .then() and .catch().


7. Async/Await ⏳

async/await makes handling asynchronous code cleaner and more readable.

Example

async function fetchData() {
    try {
        let response = await fetch("https://jsonplaceholder.typicode.com/posts/1");
        let data = await response.json();
        console.log(data);
    } catch (error) {
        console.log("Error:", error);
    }
}

fetchData();
Enter fullscreen mode Exit fullscreen mode

Why use async/await?

βœ”οΈ Avoids callback hell

βœ”οΈ Improves readability

βœ”οΈ Easier error handling using try...catch


πŸš€ Summary

  • Scope: Determines where variables are accessible.
  • Hoisting: Moves function declarations and var variables to the top before execution.
  • Function Declarations vs Expressions: Declarations are hoisted, expressions are not.
  • Arrow Functions: Shorter syntax, no this binding.
  • Promises: Handle async operations with .then() and .catch().
  • Fetch API: Used for making network requests.
  • Async/Await: Syntactic sugar over Promises for cleaner async code.

πŸ”Ή Master these concepts, and you're on your way to becoming a JavaScript pro! πŸš€

Image of Datadog

Create and maintain end-to-end frontend tests

Learn best practices on creating frontend tests, testing on-premise apps, integrating tests into your CI/CD pipeline, and using Datadog’s testing tunnel.

Download The Guide

Top comments (0)

Qodo Takeover

Introducing Qodo Gen 1.0: Transform Your Workflow with Agentic AI

Rather than just generating snippets, our agents understand your entire project context, can make decisions, use tools, and carry out tasks autonomously.

Read full post