What is Hoisting in JavaScript?

Hoisting is a behavior in JavaScript where variable and function declarations are moved to the top of their containing scope during the compilation phase, before the code is executed.

This means that we can access variables and functions before they are declared in the code.

However, it’s important to note that only the declarations are hoisted, not the initializations or assignments. This means that the variable or function is technically accessible from the beginning of its scope, but its value or assignment will not be available until the actual line of code where it is declared.

Here are a few examples to illustrate hoisting:

  1. Variable Hoisting:
console.log(x); // Output: undefined
var x = 5;

In this example, even though the console.log() statement comes before the variable x is declared and assigned a value, it does not result in an error.

The variable x is hoisted to the top of its scope (global or function) and is initialized with a value of undefined. Only at the line var x = 5; is the variable assigned the value 5.

  1. Function Hoisting:
foo(); // Output: "Hello, I am foo!"
function foo() {
  console.log("Hello, I am foo!");
}

In this example, the function foo() is called before it is declared in the code. However, due to hoisting, the function declaration is moved to the top of its scope, allowing it to be called successfully.

It’s important to understand that hoisting applies to variable and function declarations, but not to variable assignments or function expressions.

Declarations made with let, const, or class are also not hoisted.

To avoid confusion and make your code more readable, it is generally recommended to declare variables and functions at the top of their scope, even though hoisting may allow them to be used before their declarations.

What is the main difference between let var and const?

In JavaScript, let, var, and const are used to declare variables.
They have some similarities but also some important differences.

The main differences between let, var, and const are as follows:

  1. Scope:
    Variables declared with var have function scope or global scope, meaning they are accessible throughout the entire function or global environment. On the other hand, variables declared with let and const have block scope, which means they are only accessible within the nearest enclosing block (typically within curly braces {}).
  2. Hoisting:
    Variables declared with var are hoisted, which means that they are moved to the top of their scope during the compilation phase. This allows you to access var variables before they are declared in the code. Variables declared with let and const, however, are not hoisted. They are only accessible after they are declared.
  3. Reassignment:
    Variables declared with var and let can be reassigned to a new value. For example, you can write var x = 5; x = 10; or let y = 7; y = 15;. On the other hand, variables declared with const are constants, which means their value cannot be changed once assigned. If you try to reassign a const variable, it will result in an error.
  4. Temporal Dead Zone (TDZ):
    Variables declared with let and const are subject to the concept of TDZ. This means that if you try to access them before they are declared, you will get a ReferenceError. This is different from var, which can be accessed before its declaration (although it will have the value undefined).
  5. Block redeclaration: Variables declared with var can be redeclared within the same scope without causing an error. This can lead to potential bugs and confusion. Variables declared with let and const, however, cannot be redeclared within the same block scope. Attempting to do so will result in a SyntaxError.

In general, it is recommended to use let when you need to reassign a variable, and const when you want to declare a constant that will not be reassigned.

The use of var is less common nowadays, but it still has its use cases, especially when you need function or global scope variables.

Advanced-level JavaScript concepts and examples

advanced-level JavaScript concepts and examples

  1. Prototypes and Prototypal Inheritance:
    JavaScript uses prototypal inheritance to share properties and methods between objects.
// Constructor Function
function Person(name, age) {
  this.name = name;
  this.age = age;
}

// Prototype Method
Person.prototype.greet = function () {
  console.log("Hello, " + this.name + "!");
};

let person = new Person("John", 25);
person.greet();
  1. Closures:
    Closures allow functions to access variables from an outer function, even after the outer function has returned.
function outer() {
  let count = 0;

  function inner() {
    count++;
    console.log(count);
  }

  return inner;
}

let counter = outer();
counter();
counter();
  1. Event Handling:
    JavaScript enables you to handle and respond to various events, such as clicks and keypresses, in web applications.
let button = document.querySelector("#myButton");

button.addEventListener("click", function () {
  console.log("Button clicked!");
});
  1. Asynchronous Programming:
    JavaScript provides mechanisms to handle asynchronous operations, such as callbacks, promises, and async/await.
// Callbacks
function fetchData(callback) {
  setTimeout(() => {
    callback("Data fetched successfully!");
  }, 2000);
}

fetchData(function (data) {
  console.log(data);
});

// Promises
function fetchData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("Data fetched successfully!");
    }, 2000);
  });
}

fetchData().then(function (data) {
  console.log(data);
});

// Async/Await
async function processData() {
  try {
    const data = await fetchData();
    console.log(data);
  } catch (error) {
    console.log("Error:", error);
  }
}

processData();
  1. Modules:
    ES6 modules provide a standardized way to organize and share code between JavaScript files.
// Module: math.js
export function add(a, b) {
  return a + b;
}

// Module: main.js
import { add } from "./math.js";

console.log(add(5, 3));
  1. Regular Expressions:
    Regular expressions allow for advanced pattern matching and manipulation of strings.
let pattern = /hello/i;
let str = "Hello, World!";

console.log(pattern.test(str)); // true
console.log(pattern.exec(str)); // ["Hello"]
console.log(str.replace(pattern, "Hi")); // "Hi, World!"
  1. Error Handling and Debugging:
    JavaScript provides error handling mechanisms like try/catch blocks, as well as debugging tools and techniques.
try {
  // Code that might throw an error
  throw new Error("Something went wrong");
} catch (error) {
  console.log("Error:", error);
}

// Debugging with console
console.log("Debugging message");

// Using breakpoints in browser developer tools
  1. Web APIs:
    JavaScript provides access to various Web APIs, enabling interaction with browser features and external services.
// Fetch API
fetch("https://api.example.com/data")
  .then(function (response) {
    return response.json();
  })
  .then(function (data) {
    console.log(data);
  })
  .catch(function (error) {
    console.log("Error:", error);
  });

// Geolocation API
navigator.geolocation.getCurrentPosition(function (position) {
  console.log(position.coords.latitude, position.coords.longitude);
});

These advanced-level JavaScript concepts and examples will help you tackle complex programming challenges

Intermediate-level JavaScript tutorial with examples

intermediate-level JavaScript tutorial with examples:

  1. Arrow Functions:
    Arrow functions provide a shorter syntax for writing function expressions.
// Regular Function
function square(num) {
  return num * num;
}

// Arrow Function
const square = (num) => num * num;
  1. Higher-Order Functions:
    Higher-order functions are functions that take other functions as arguments or return functions.
// Higher-Order Function
function doMath(operation, num1, num2) {
  return operation(num1, num2);
}

// Callback Functions
function add(a, b) {
  return a + b;
}

function subtract(a, b) {
  return a - b;
}

console.log(doMath(add, 5, 3));
console.log(doMath(subtract, 5, 3));
  1. Destructuring Assignment:
    Destructuring assignment allows you to extract values from arrays or objects into separate variables.
// Array Destructuring
let numbers = [1, 2, 3];
let [a, b, c] = numbers;
console.log(a, b, c);

// Object Destructuring
let person = { name: "John", age: 25 };
let { name, age } = person;
console.log(name, age);
  1. Spread Operator:
    The spread operator allows you to spread elements of an iterable (like an array) into individual elements.
let numbers = [1, 2, 3];
let newNumbers = [...numbers, 4, 5];
console.log(newNumbers);
  1. Classes and Objects:
    JavaScript supports object-oriented programming with classes and objects.
class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  greet() {
    console.log("Hello, " + this.name + "!");
  }
}

let person = new Person("John", 25);
person.greet();
  1. Promises and Async/Await:
    Promises and async/await are used for handling asynchronous operations in a more readable and sequential manner.
function fetchData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("Data fetched successfully!");
    }, 2000);
  });
}

async function processData() {
  try {
    const data = await fetchData();
    console.log(data);
  } catch (error) {
    console.log("Error:", error);
  }
}

processData();
  1. Modules:
    Modules help organize and split code into separate files, allowing for better code organization and reusability.
// Module: math.js
export function add(a, b) {
  return a + b;
}

// Module: main.js
import { add } from "./math.js";

console.log(add(5, 3));
  1. Error Handling:
    JavaScript provides error handling mechanisms like try/catch blocks to handle and manage exceptions.
try {
  // Code that might throw an error
  throw new Error("Something went wrong");
} catch (error) {
  console.log("Error:", error);
}

50 JavaScript exercises along with their solutions

50 JavaScript exercises along with their solutions:

Exercise 1:
Write a program to display “Hello, World!” in the console.

console.log("Hello, World!");

Exercise 2:
Write a program to add two numbers and display the result.

let num1 = 5;
let num2 = 10;
let sum = num1 + num2;
console.log(sum);

Exercise 3:
Write a program to check if a number is positive, negative, or zero.

let number = 0;

if (number > 0) {
  console.log("Positive");
} else if (number < 0) {
  console.log("Negative");
} else {
  console.log("Zero");
}

Exercise 4:
Write a program to check if a number is even or odd.

let number = 7;

if (number % 2 === 0) {
  console.log("Even");
} else {
  console.log("Odd");
}

Exercise 5:
Write a program to find the maximum of two numbers.

let num1 = 10;
let num2 = 5;

let max = num1 > num2 ? num1 : num2;
console.log(max);

Exercise 6:
Write a program to find the minimum of two numbers.

let num1 = 10;
let num2 = 5;

let min = num1 < num2 ? num1 : num2;
console.log(min);

Exercise 7:
Write a program to check if a year is a leap year.

let year = 2020;

if ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0) {
  console.log("Leap year");
} else {
  console.log("Not a leap year");
}

Exercise 8:
Write a program to check if a string is empty or not.

let str = "";

if (str === "") {
  console.log("String is empty");
} else {
  console.log("String is not empty");
}

Exercise 9:
Write a program to check if a string is a palindrome.

let str = "madam";
let reversedStr = str.split("").reverse().join("");

if (str === reversedStr) {
  console.log("Palindrome");
} else {
  console.log("Not a palindrome");
}

Exercise 10:
Write a program to reverse a string.

let str = "Hello, World!";
let reversedStr = str.split("").reverse().join("");
console.log(reversedStr);

Exercise 11:
Write a program to find the factorial of a number.

let num = 5;
let factorial = 1;

for (let i = 1; i <= num; i++) {
  factorial *= i;
}

console.log(factorial);

Exercise 12:
Write a program to generate Fibonacci series up to a given number of terms.

let numTerms = 10;
let fibonacciSeries = [0, 1];

for (let i = 2; i < numTerms; i++) {
  let nextTerm = fibonacciSeries[i - 1] + fibonacciSeries[i - 2];
  fibonacciSeries.push(nextTerm);
}

console.log(fibonacciSeries);

Exercise 13:
Write a program to check if a number is a prime number.

let num = 17;
let isPrime = true;

for (let i = 2; i <= Math.sqrt(num); i++) {
  if (num % i === 

0) {
    isPrime = false;
    break;
  }
}

if (isPrime) {
  console.log("Prime number");
} else {
  console.log("Not a prime number");
}

Exercise 14:
Write a program to find the sum of all elements in an array.

let numbers = [1, 2, 3, 4, 5];
let sum = 0;

for (let i = 0; i < numbers.length; i++) {
  sum += numbers[i];
}

console.log(sum);

Exercise 15:
Write a program to find the maximum element in an array.

let numbers = [1, 5, 3, 9, 2];
let max = numbers[0];

for (let i = 1; i < numbers.length; i++) {
  if (numbers[i] > max) {
    max = numbers[i];
  }
}

console.log(max);

Exercise 16:
Write a program to remove duplicate elements from an array.

let numbers = [1, 2, 3, 2, 4, 1, 5, 4];
let uniqueNumbers = [];

for (let i = 0; i < numbers.length; i++) {
  if (!uniqueNumbers.includes(numbers[i])) {
    uniqueNumbers.push(numbers[i]);
  }
}

console.log(uniqueNumbers);

Exercise 17:
Write a program to count the number of vowels in a string.

let str = "Hello, World!";
let vowels = ["a", "e", "i", "o", "u"];
let count = 0;

for (let i = 0; i < str.length; i++) {
  if (vowels.includes(str[i].toLowerCase())) {
    count++;
  }
}

console.log(count);

Exercise 18:
Write a program to count the number of words in a string.

let str = "Hello, World!";
let words = str.split(" ");
let count = words.length;

console.log(count);

Exercise 19:
Write a program to check if a string is a valid email address.

let email = "test@example.com";
let regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

if (regex.test(email)) {
  console.log("Valid email address");
} else {
  console.log("Invalid email address");
}

Exercise 20:
Write a program to reverse the order of words in a string.

let str = "Hello, World!";
let reversedWords = str.split(" ").reverse().join(" ");

console.log(reversedWords);

Exercise 21:
Write a program to find the length of the longest word in a string.

let str = "Hello, World!";
let words = str.split(" ");
let maxLength = 0;

for (let i = 0; i < words.length; i++) {
  if (words[i].length > maxLength) {
    maxLength = words[i].length;
  }
}

console.log(maxLength);

Exercise 22:
Write a program to sort an array of numbers in ascending order.

let numbers = [5, 2, 9, 1, 7];
numbers.sort((a, b) => a - b);

console.log(numbers);

Exercise 23:
Write a program to sort an array of strings in alphabetical order.

let fruits = ["Apple", "Orange", "Banana", "Mango"];
fruits.sort();

console.log(fruits);

Exercise 24:
Write a program to check if two strings are an

agrams.

let str1 = "listen";
let str2 = "silent";

let sortedStr1 = str1.toLowerCase().split("").sort().join("");
let sortedStr2 = str2.toLowerCase().split("").sort().join("");

if (sortedStr1 === sortedStr2) {
  console.log("Anagrams");
} else {
  console.log("Not anagrams");
}

Exercise 25:
Write a program to find the sum of natural numbers up to a given number.

let num = 10;
let sum = 0;

for (let i = 1; i <= num; i++) {
  sum += i;
}

console.log(sum);

Exercise 26:
Write a program to find the factorial of a number using recursion.

function factorial(num) {
  if (num === 0) {
    return 1;
  } else {
    return num * factorial(num - 1);
  }
}

console.log(factorial(5));

Exercise 27:
Write a program to check if a string is a valid palindrome ignoring spaces and punctuation.

function isPalindrome(str) {
  let regex = /[^\w]|_/g;
  let cleanedStr = str.toLowerCase().replace(regex, "");
  let reversedStr = cleanedStr.split("").reverse().join("");

  return cleanedStr === reversedStr;
}

console.log(isPalindrome("A man, a plan, a canal, Panama!"));

Exercise 28:
Write a program to convert a string to title case.

function toTitleCase(str) {
  let words = str.split(" ");
  let titleCaseWords = [];

  for (let i = 0; i < words.length; i++) {
    let word = words[i];
    let titleCaseWord = word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
    titleCaseWords.push(titleCaseWord);
  }

  return titleCaseWords.join(" ");
}

console.log(toTitleCase("hello, world!"));

Exercise 29:
Write a program to find the second largest element in an array.

let numbers = [5, 2, 9, 1, 7];
numbers.sort((a, b) => b - a);

console.log(numbers[1]);

Exercise 30:
Write a program to remove all falsy values from an array.

let array = [0, 1, false, true, "", "hello", null, undefined, NaN];
let filteredArray = array.filter(Boolean);

console.log(filteredArray);

Exercise 31:
Write a program to find the median of an array of numbers.

let numbers = [5, 2, 9, 1, 7];
numbers.sort((a, b) => a - b);

let median;

if (numbers.length % 2 === 0) {
  let midIndex = numbers.length / 2;
  median = (numbers[midIndex - 1] + numbers[midIndex]) / 2;
} else {
  let midIndex = Math.floor(numbers.length / 2);
  median = numbers[midIndex];
}

console.log(median);

Exercise 32:
Write a program to find the sum of all even numbers in an array.

let numbers = [1, 2, 3, 4, 5];
let sum = 0;

for (let i = 0; i < numbers.length; i++) {
  if (numbers[i] % 2 === 0) {
    sum += numbers[i];
  }
}

console.log(sum);

Exercise 33:
Write a program to find the intersection of two arrays

.

let array1 = [1, 2, 3, 4, 5];
let array2 = [4, 5, 6, 7, 8];
let intersection = [];

for (let i = 0; i < array1.length; i++) {
  if (array2.includes(array1[i])) {
    intersection.push(array1[i]);
  }
}

console.log(intersection);

Exercise 34:
Write a program to convert a number to binary.

let num = 10;
let binary = num.toString(2);

console.log(binary);

Exercise 35:
Write a program to convert a binary number to decimal.

let binary = "1010";
let decimal = parseInt(binary, 2);

console.log(decimal);

Exercise 36:
Write a program to find the sum of digits of a number.

let num = 12345;
let sum = 0;

while (num > 0) {
  sum += num % 10;
  num = Math.floor(num / 10);
}

console.log(sum);

Exercise 37:
Write a program to find the largest element in an array using reduce() method.

let numbers = [5, 2, 9, 1, 7];
let max = numbers.reduce((a, b) => Math.max(a, b));

console.log(max);

Exercise 38:
Write a program to find the smallest element in an array using reduce() method.

let numbers = [5, 2, 9, 1, 7];
let min = numbers.reduce((a, b) => Math.min(a, b));

console.log(min);

Exercise 39:
Write a program to remove duplicate elements from an array using the filter() method.

let numbers = [1, 2, 3, 2, 4, 1, 5, 4];
let uniqueNumbers = numbers.filter((value, index, array) => array.indexOf(value) === index);

console.log(uniqueNumbers);

Exercise 40:
Write a program to find the average of numbers in an array.

let numbers = [1, 2, 3, 4, 5];
let sum = numbers.reduce((a, b) => a + b);
let average = sum / numbers.length;

console.log(average);

Exercise 41:
Write a program to shuffle an array.

let array = [1, 2, 3, 4, 5];

for (let i = array.length - 1; i > 0; i--) {
  let j = Math.floor(Math.random() * (i + 1));
  [array[i], array[j]] = [array[j], array[i]];
}

console.log(array);

Exercise 42:
Write a program to find the number of occurrences of a specific element in an array.

let array = [1, 2, 3, 2, 4, 1, 5, 4];
let element = 2;
let count = array.reduce((acc, value) => (value === element ? acc + 1 : acc), 0);

console.log(count);

Exercise 43:
Write a program to check if a number is a perfect number.

function isPerfectNumber(num) {
  let sum = 0;

  for (let i = 1; i < num; i++) {
    if (num % i === 0) {
      sum += i;
    }
  }

  return sum === num;
}

console.log(is

PerfectNumber(28));

Exercise 44:
Write a program to find the power of a number.

function power(base, exponent) {
  let result = 1;

  for (let i = 0; i < exponent; i++) {
    result *= base;
  }

  return result;
}

console.log(power(2, 3));

Exercise 45:
Write a program to find the number of words in a sentence.

let sentence = "Hello, World!";
let words = sentence.split(" ");
let count = words.length;

console.log(count);

Exercise 46:
Write a program to find the sum of digits of a number using recursion.

function sumOfDigits(num) {
  if (num === 0) {
    return 0;
  } else {
    return (num % 10) + sumOfDigits(Math.floor(num / 10));
  }
}

console.log(sumOfDigits(12345));

Exercise 47:
Write a program to find the GCD (Greatest Common Divisor) of two numbers.

function gcd(a, b) {
  if (b === 0) {
    return a;
  } else {
    return gcd(b, a % b);
  }
}

console.log(gcd(12, 18));

Exercise 48:
Write a program to convert a decimal number to binary using recursion.

function decimalToBinary(num) {
  if (num === 0) {
    return "";
  } else {
    return decimalToBinary(Math.floor(num / 2)) + (num % 2);
  }
}

console.log(decimalToBinary(10));

Exercise 49:
Write a program to find the LCM (Least Common Multiple) of two numbers.

function lcm(a, b) {
  let max = Math.max(a, b);
  let min = Math.min(a, b);

  for (let i = max; ; i += max) {
    if (i % min === 0) {
      return i;
    }
  }
}

console.log(lcm(12, 18));

Exercise 50:
Write a program to find the number of digits in a number.

let num = 12345;
let count = num.toString().length;

console.log(count);

Simple calculator in JavaScript

<!DOCTYPE html>
<html>
<head>
<title>Calculator</title>
<style>
.calculator {
width: 200px;
border: 1px solid #ccc;
padding: 10px;
}
.calculator input {
width: 100%;
margin-bottom: 5px;
}
.calculator .btn {
width: 48%;
margin: 1%;
}
</style>
</head>
<body>
<div class=”calculator”>
<input type=”text” id=”result” readonly>
<button class=”btn” onclick=”appendToResult(‘1’)”>1</button>
<button class=”btn” onclick=”appendToResult(‘2’)”>2</button>
<button class=”btn” onclick=”appendToResult(‘3’)”>3</button>
<button class=”btn” onclick=”appendToResult(‘+’)”>+</button>
<button class=”btn” onclick=”appendToResult(‘4’)”>4</button>
<button class=”btn” onclick=”appendToResult(‘5’)”>5</button>
<button class=”btn” onclick=”appendToResult(‘6’)”>6</button>
<button class=”btn” onclick=”appendToResult(‘-‘)”>-</button>
<button class=”btn” onclick=”appendToResult(‘7’)”>7</button>
<button class=”btn” onclick=”appendToResult(‘8’)”>8</button>
<button class=”btn” onclick=”appendToResult(‘9’)”>9</button>
<button class=”btn” onclick=”appendToResult(‘*’)”>*</button>
<button class=”btn” onclick=”appendToResult(‘0’)”>0</button>
<button class=”btn” onclick=”appendToResult(‘.’)”>.</button>
<button class=”btn” onclick=”calculate()”>=</button>
<button class=”btn” onclick=”appendToResult(‘/’)”>/</button>
<button class=”btn” onclick=”clearResult()”>C</button>
</div>

<script>
function appendToResult(value) {
var resultInput = document.getElementById(‘result’);
resultInput.value += value;
}

function calculate() {
var resultInput = document.getElementById(‘result’);
var result = eval(resultInput.value);
resultInput.value = result;
}

function clearResult() {
var resultInput = document.getElementById(‘result’);
resultInput.value = ”;
}
</script>
</body>
</html>