Javascript Interview Questions - Intermediate
Published: 2023-10-11 06:10:14

### 1. Explain the concepts of call, apply, and bind in JavaScript. Provide examples.
  
  *Description*: call, apply, and bind are methods used to change the this value in functions.

   ```javascript
    const person = { name: 'Alice' };

    function greet(greeting) {
      console.log(`${greeting}, ${this.name}!`);
    }

    greet.call(person, 'Hello'); // Output: Hello, Alice!
    greet.apply(person, ['Hi']); // Output: Hi, Alice!

    const greetBound = greet.bind(person);
    greetBound('Hey'); // Output: Hey, Alice!
   ```

### 2. Explain the difference between `let`, `const`, and `var` in JavaScript.
    
    In JavaScript, `let`, `const`, and `var` are used to declare variables. Each has different scoping rules and reassignment capabilities, making them suitable for different use cases.

      #### 1. **`var`**:
        - `var` was traditionally used to declare variables in JavaScript.
        - Variables declared with `var` are function-scoped, meaning they are only accessible within the function they are declared in.
        - Variables declared with `var` can be redeclared and updated.

        ```javascript
        function exampleVar() {
          var x = 10;
          if (true) {
            var x = 20;  // This reassigns the existing variable 'x'
            console.log(x);  // Output: 20
          }
          console.log(x);  // Output: 20 (not 10)
        }
        ```

      #### 2. **`let`**:
        - Introduced in ES6, `let` allows block-scoping of variables, making them accessible only within the block they are defined in (e.g., if, for, while blocks).
        - Variables declared with `let` can be reassigned but cannot be redeclared in the same scope.

        ```javascript
        function exampleLet() {
          let y = 30;
          if (true) {
            let y = 40;  // This creates a new block-scoped variable 'y'
            console.log(y);  // Output: 40
          }
          console.log(y);  // Output: 30 (not affected by the inner 'y')
        }
        ```

      #### 3. **`const`**:
        - Also introduced in ES6, `const` is used to declare constants whose values cannot be reassigned.
        - Variables declared with `const` are block-scoped like `let`.
        - A `const` variable must be assigned a value during declaration and cannot be left uninitialized.

        ```javascript
        function exampleConst() {
          const z = 50;
          // z = 60;  // Error: Assignment to a constant variable
          console.log(z);  // Output: 50
        }
        ```

      In summary:
        - Use `var` for traditional function-scoped variables (but it's recommended to use `let` and `const` in modern JavaScript).
        - Use `let` when you need to reassign a variable's value within the same block.
        - Use `const` when you want to define a constant value that should not be reassigned.

        It's good practice to use `let` and `const` over `var` for better scoping and to avoid potential issues related to hoisting and unintended variable reassignment.

### 3. What is a closure in JavaScript? Provide an example.
   
   *Answer:*
   ```javascript
   function outer() {
     const message = 'Hello';
     function inner() {
       console.log(message);
     }
     return inner;
   }
   
   const innerFunc = outer();
   innerFunc();  // Output: 'Hello'
   ```

### 4. What is event delegation in JavaScript?
   *Answer:* Event delegation is a technique where a single event listener is attached to a common ancestor, allowing events to be handled for multiple children.

### 5. What is the difference between `==` and `===` in JavaScript?
   *Answer:* `==` checks for equality with type coercion, while `===` checks for strict equality without type coercion.

### 6. What is the purpose of the `async` and `await` keywords in JavaScript?
   *Answer:* `async` and `await` are features introduced in ES2017 (ES8) that make working with asynchronous code more readable and easier to manage. They are built on top of promises.

    #### 1. **`async`**:
      - `async` is used to declare that a function will work with promises and may use `await` within its body.
      - It allows a function to return a promise implicitly.
      - Functions marked with `async` always return a promise, even if you return a non-promise value.

      ```javascript
      async function asyncFunction() {
        return 42; // Equivalent to returning Promise.resolve(42)
      }
      ```

    #### 2. **`await`**:
      - `await` can only be used within an `async` function.
      - It is used to pause the execution of the function until a promise is resolved or rejected.
      - It "awaits" the result of a promise and returns the resolved value or throws an error for a rejected promise.

      ```javascript
      async function fetchUserData() {
        try {
          const response = await fetch('https://api.example.com/user');
          const data = await response.json();
          return data;
        } catch (error) {
          console.error('Error:', error);
        }
      }
      ```

    #### 3. **Difference from `.then()`**:
    - While both `await` and `.then()` handle asynchronous operations, the key difference lies in how they manage the flow of asynchronous code.
    - `.then()` is used with promises and is chaining-based, where each `.then()` function returns a promise and allows you to chain further operations.
    - `await`, on the other hand, allows for more synchronous-like code within `async` functions, making asynchronous code appear more linear and readable.

    ```javascript
    // Using .then()
    fetch('https://api.example.com/data')
      .then(response => response.json())
      .then(data => console.log(data))
      .catch(error => console.error('Error:', error));

    // Using await
    async function fetchData() {
      try {
        const response = await fetch('https://api.example.com/data');
        const data = await response.json();
        console.log(data);
      } catch (error) {
        console.error('Error:', error);
      }
    }
    ```
    In summary, `async` and `await` make asynchronous code look and behave more like synchronous code, enhancing readability and maintainability, especially when dealing with promises.

### 7. Explain what the `this` keyword refers to in JavaScript.
   
   *Answer:*
   `this` refers to the object on which a method is being called.

### 8. What is a promise in JavaScript? Provide an example of creating and using a promise.
   
   *Answer:*
   ```javascript
   const myPromise = new Promise((resolve, reject) => {
     setTimeout(() => {
       resolve('Promise resolved!');
     }, 2000);
   });

   myPromise.then((result) => {
     console.log(result);
   }).catch((error) => {
     console.error(error);
   });
   ```

### 9. What is a callback function in JavaScript? Provide an example.
   
   *Answer:*
   ```javascript
   function fetchData(callback) {
     setTimeout(() => {
       callback('Data fetched!');
     }, 2000);
   }

   fetchData((data) => {
     console.log(data);
   });
   ```

### 10. What is the difference between `null` and `undefined` in JavaScript?
    
    *Answer:*
    `null` is an assignment value representing no value or no object, while `undefined` is a primitive value automatically assigned to uninitialized variables.

### 11. What is event bubbling in JavaScript?
    
    *Answer:*
    Event bubbling is the propagation of an event from the target element up to its parent and higher ancestors in the DOM tree.

### 12. What is event.preventDefault()? Provide an example of its usage.
    Description: event.preventDefault() is used to prevent the default behavior of an event, such as form submission or link navigation.

    *Answer:*
    ```js
    const submitButton = document.getElementById('submitButton');
    submitButton.addEventListener('click', event => {
      event.preventDefault(); // Prevents form submission
      console.log('Form submission prevented.');
    });
    ```

### 13. What are arrow functions in JavaScript? Provide an example.
    *Answer:*
    ```javascript
    const add = (a, b) => a + b;
    console.log(add(2, 3));  // Output: 5
    ```

### 14. What is the purpose of the `localStorage` and `sessionStorage` objects in JavaScript?
    
    *Answer:*
    They provide a way to store key-value pairs in a web browser, with `localStorage` persisting even after the browser is closed and reopened, and `sessionStorage` existing only for the duration of the page session.

### 15. Explain event handling in JavaScript and provide an example of attaching an event listener.
    
    *Answer:*
    ```javascript
    const button = document.getElementById('myButton');

    button.addEventListener('click', () => {
      console.log('Button clicked!');
    });
    ```

### 16. What is the difference between `map()` and `forEach()` array methods in JavaScript?
    *Answer:* `map()` returns a new array with the results of a function applied to each element, while `forEach()` only iterates over the array and does not return a new array.

### 17. What is a RESTful API and how do you make a GET request using JavaScript?
    
    
    *Answer:*
    ```javascript
    fetch('https://api.example.com/data')
      .then(response => response.json())
      .then(data => console.log(data))
      .catch(error => console.error('Error:', error));
    ```

### 18. What is the purpose of the `use strict` directive in JavaScript?
    The "use strict" directive in JavaScript is used to enable a stricter interpretation of the code, catching common mistakes and preventing the use of certain error-prone features. When this directive is applied, the JavaScript engine enforces stricter rules for writing code.

    #### 1. Purpose:
      - It helps in writing more reliable and maintainable code by identifying and disallowing potentially error-prone behavior.
      - It prevents the accidental creation of global variables by enforcing block scope rules with `let` and `const`.
      - It disallows the use of certain language features that are deprecated or considered bad practice.

    #### 2. Example:
      ```javascript
      // Without "use strict"
      function withoutStrict() {
        variable = 10;  // This will create a global variable accidentally
        console.log(variable);
      }

      withoutStrict();  // Output: 10

      // With "use strict"
      function withStrict() {
        'use strict';
        variable = 20;  // This will throw a ReferenceError
        console.log(variable);
      }

      withStrict();  // Error: variable is not defined
      ```

      In the first example without "use strict," `variable` is mistakenly created as a global variable, which can lead to unexpected behavior and bugs in a larger codebase.

      In the second example with "use strict," attempting to assign a value to `variable` without declaring it with `var`, `let`, or `const` will throw a `ReferenceError`, indicating that `variable` is not defined. This helps catch potential bugs and encourages better coding practices.

      To enable "use strict" globally in a script, you can add it at the beginning of your JavaScript file or within a function. For modern JavaScript development, it's recommended to use "use strict" to enhance code quality and reduce the risk of errors.

### 19. Explain hoisting in JavaScript.
    *Answer:* 
    
    - Hoisting is a JavaScript mechanism where variable and function declarations are moved to the top of their containing scope during the compile phase.

    ```js
    console.log(x);  // Output: undefined
    var x = 10;
    console.log(x);  // Output: 10
    ```

### 20. How do you handle errors in JavaScript? Provide an example of using a `try...catch` block.
    *Answer:*
    ```javascript
    try {
      // Code that may throw an error
      const result = 10 / 0;
      console.log(result);
    } catch (error) {
      console.error('An error occurred:', error.message);
    }
    ```