Frontend Flashcards

1
Q

What is the event loop, explain how it works.

A

The event loop is a fundamental aspect of how JavaScript handles asynchronous operations, ensuring that it remains non-blocking despite being single-threaded. Here’s how it works:

  1. JavaScript Runtime Environment: JavaScript, typically running in a browser or in Node.js, includes a call stack, a heap, and a message queue (or task queue).
  2. Call Stack: This is where the JavaScript engine keeps track of the execution context of function calls. When a function is called, it is added to the stack. When the function returns, it is removed from the stack.
  3. Heap: This is where objects are stored.
  4. Message Queue (Task Queue): This is where asynchronous tasks wait until they are ready to be executed. For example, when an asynchronous operation like setTimeout or an API request is initiated, the corresponding callback is pushed into the queue.
  5. Event Loop’s Role:
    • The event loop continuously checks if the call stack is empty.
    • If the call stack is empty and there are callback functions in the message queue, the event loop moves the first callback from the queue to the call stack.
    • This callback is then executed.
  6. Types of Tasks: The event loop handles different kinds of tasks. In browsers, there are macro-tasks (like timeouts, user interactions) and micro-tasks (like promises). Micro-tasks have higher priority and are executed immediately after the currently running script and before jumping into the next macro-task.
  7. Non-Blocking Behavior: While executing long-running tasks, JavaScript can still handle UI updates and respond to user events, thanks to the event loop. It allows asynchronous operations to be processed in the background, and their callbacks to be executed only when the call stack is clear.
  8. Example Flow:
    • A function is called and added to the call stack.
    • If this function initiates an asynchronous operation, the operation is processed outside of the JavaScript engine, and its callback function is placed in the message queue.
    • The event loop checks the call stack; if it’s empty, it takes the callback from the queue and places it on the stack.
    • The callback function is executed.

In summary, the event loop enables JavaScript to perform non-blocking asynchronous operations by using a call stack for function execution, a task queue for managing callbacks associated with asynchronous operations, and the event loop itself to ensure callbacks are executed at the right time. This design is key to JavaScript’s efficiency in handling tasks like network requests, I/O operations, and timers.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

What is a highier order function and give examples

A

A higher-order function in programming, particularly in JavaScript, is a function that either takes one or more functions as arguments (i.e., procedural parameters), or returns a function as its result. This concept is a key part of functional programming and is very common in JavaScript due to its support for first-class functions.

Examples of Higher-Order Functions:

  1. Functions that Take Other Functions as Arguments:
    • Array.prototype.map:
      • This method creates a new array by calling a provided function on every element in the calling array.
      • Example: const doubled = [1, 2, 3].map((num) => num * 2); // [2, 4, 6]
    • Array.prototype.filter:
      • This method creates a new array with all elements that pass the test implemented by the provided function.
      • Example: const evens = [1, 2, 3, 4].filter((num) => num % 2 === 0); // [2, 4]
    • Array.prototype.reduce:
      • This method executes a reducer function on each element of the array, resulting in a single output value.
      • Example: const sum = [1, 2, 3, 4].reduce((accumulator, num) => accumulator + num, 0); // 10
  2. Functions that Return Other Functions:
    • Function Factories:
      • These are functions that create and return new functions.
      • Example:
        javascript
        function makeMultiplier(multiplier) {
            return function (x) {
                return x * multiplier;
            };
        }
        const double = makeMultiplier(2);
        console.log(double(3)); // 6
    • Function Composition:
      • This involves creating a function that composes multiple functions, passing the output of one function as the input to another.
      • Example:
        javascript
        function compose(f, g) {
            return function (x) {
                return f(g(x));
            };
        }
        const increment = (x) => x + 1;
        const double = (x) => x * 2;
        const doubleThenIncrement = compose(increment, double);
        console.log(doubleThenIncrement(3)); // 7

Higher-order functions are a powerful concept in JavaScript, allowing for more abstract, concise, and reusable code. They are especially useful in working with arrays, asynchronous operations, and in many patterns that require encapsulation or composition of behavior.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

What is a prototype in javascript?

A

In JavaScript, a prototype is a fundamental concept that plays a central role in the language’s object-oriented programming model. It is used for implementing inheritance and sharing properties and methods across objects. Here’s a detailed explanation:

Basic Concept of Prototype

  1. Every JavaScript Function has a prototype Property:
    • This property is an object (called the prototype object) where you can attach properties and methods that you want to inherit.
  2. Objects Have a \_\_proto\_\_ Property:
    • When you create an object from a constructor function, the newly created object internally links to the constructor function’s prototype object through its \_\_proto\_\_ property. This is often referred to as the object’s “prototype”.
  3. Prototype Chain for Inheritance:
    • When you try to access a property or method of an object, JavaScript will first search on the object itself. If it’s not found, JavaScript will look up the prototype chain (the \_\_proto\_\_ property) until it finds the property or method or reaches the end of the chain (null).

Example of Prototypal Inheritance

Consider this example:

```javascript
function Animal(name) {
this.name = name;
}

Animal.prototype.speak = function() {
console.log(${this.name} makes a noise.);
}

const dog = new Animal(‘Dog’);

dog.speak(); // Dog makes a noise.
~~~

In this example, Animal is a constructor function. We add a method speak to Animal.prototype. When we create a new Animal instance (a dog), it inherits the speak method from its prototype.

Prototype vs Class-based OOP

  • Prototype-based: JavaScript is often described as a prototype-based language. Each object can serve as a prototype for another object. This is different from class-based inheritance where classes define the blueprint of objects.
  • Classes in JavaScript: With ES6, JavaScript introduced a class syntax. However, this is syntactic sugar over JavaScript’s existing prototype-based inheritance. The class keyword makes the inheritance model more familiar to developers from a class-based language background, but under the hood, JavaScript still uses prototypes.

Importance of Prototypes

  • Efficient Memory Usage: If a method is added to an object’s prototype, all instances of that object share the same method, rather than each instance having its own copy of the method. This is more memory-efficient.
  • Dynamic Nature: You can add or modify methods and properties on a prototype at runtime, which will immediately be available to all objects linked to that prototype.

Understanding prototypes is crucial for effective JavaScript programming, especially for inheritance, creating reusable code, and optimizing performance.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Explain the “this” keyword in Javascript

A

The this keyword in JavaScript is a special identifier that’s automatically defined in the scope of every function and refers to the object that is executing the current piece of code. Understanding this is crucial because its value can change depending on the context in which the function is called. Here are key aspects of how this behaves in different scenarios:

1. Global Context
- In the global execution context (outside of any function), this refers to the global object.
- In a browser, the global object is window, so this in a global context typically refers to window.

2. Function Context
- Regular Functions:
- In a regular function call (i.e., not as a method of an object), this depends on how the function is called and the strict mode setting.
- In strict mode, this will be undefined because strict mode doesn’t allow default binding to the global object.
- In non-strict mode, this will default to the global object.
- Method Calls:
- When a function is called as a method of an object, this refers to the object the method is called on.

3. Constructor Context
- In a constructor function, which is used with the new keyword, this refers to the newly created object.

4. Arrow Functions
- Arrow functions do not have their own this context. They inherit this from the parent scope at the time they are defined. This is a key feature that makes arrow functions behave differently from regular functions.

5. Explicit Binding
- Functions in JavaScript can have their context (this) explicitly set using methods like apply, call, and bind.
- call and apply are used to invoke a function with an explicitly specified this context and arguments.
- bind creates a new function with a given this value and arguments, pre-filled.

Examples:

  1. Global Context:
    javascript
    console.log(this); // In a browser, this will log the window object.
  2. Function Context:
    javascript
    function func() {
      return this;
    }
    func(); // `this` will be `window` in non-strict mode, `undefined` in strict mode.
  3. Method Call:
    javascript
    const obj = {
      method: function() {
        return this;
      }
    };
    obj.method(); // `this` refers to `obj`.
  4. Constructor Context:
    javascript
    function Constructor() {
      this.value = 'example';
    }
    const instance = new Constructor();
    console.log(instance.value); // 'example'
  5. Arrow Function:
    javascript
    const obj = {
      regularFunc: function() {
        return function() { return this; };
      },
      arrowFunc: function() {
        return () => this;
      }
    };
    obj.regularFunc()(); // `this` is `window` or `undefined` (in strict mode)
    obj.arrowFunc()(); // `this` refers to `obj`

Understanding the context and the rules governing this in JavaScript is essential for writing correct and predictable code, especially when dealing with object-oriented programming or handling event callbacks.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Explain how reactjs works

A

React is a popular JavaScript library for building user interfaces, especially single-page applications. It’s known for its efficient rendering and the concept of components. Here’s an overview of how React works:

1. Components
- Building Blocks: React apps are built using components. These components are reusable and can manage their own state. A component can be a class or a function.
- Hierarchy: Components are often nested, creating a component hierarchy. Parent components can pass data to child components via props.

2. JSX (JavaScript XML)
- Syntax Extension: React introduces JSX, a syntax extension that allows you to write HTML structures in the same file as JavaScript code. This makes the code more readable and easier to write.
- Transpilation: JSX is not standard JavaScript and needs to be transpiled into JavaScript. Tools like Babel are used to convert JSX into React.createElement calls.

3. Virtual DOM
- Efficient Updates: React uses a Virtual DOM, a lightweight copy of the actual DOM. When a component’s state changes, React first changes the object in the Virtual DOM.
- Reconciliation: React then compares the updated Virtual DOM with the previous version and calculates the best way to make these changes on the real DOM. This process is known as “reconciliation”.
- Minimal DOM Manipulation: This approach minimizes direct manipulation of the DOM, which is slow, and thus enhances performance.

4. State and Props
- State: State is an object that determines the behavior and rendering of components. It’s local and encapsulated in the component.
- Props: Props (short for “properties”) are read-only and allow data to pass from parent to child components.

5. Lifecycle Methods
- Classes: Class components have lifecycle methods (like componentDidMount, componentDidUpdate, and componentWillUnmount) that run at specific points in a component’s life.
- Hooks: Functional components use Hooks (like useState, useEffect) to “hook into” React features.

6. Hooks
- Functional Components: Hooks allow functional components to manage state and side effects, making class components mostly unnecessary.
- Common Hooks: useState for state management, useEffect for side effects, and useContext for accessing the context API.

7. Context API
- Global State Management: Allows passing data through the component tree without having to pass props down manually at every level.

8. React Router
- Routing: Though not part of React core, React Router is a popular library to add navigation and routing to React applications.

9. Performance Optimization
- Memoization: React has features like React.memo, useMemo, and useCallback to help avoid unnecessary re-renders and computations.

10. Server-Side Rendering (SSR)
- SEO and Performance: Frameworks like Next.js enable React apps to be rendered on the server, improving load times and SEO.

Summary
React’s combination of the virtual DOM, component-based architecture, and efficient update mechanism makes it powerful for building dynamic and high-performing web applications. Its declarative nature allows developers to describe UIs and let React handle the updates and rendering efficiently.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

What is a thunk in react redux?

A

A thunk in the context of React Redux is a concept used for handling asynchronous actions in a Redux application. It’s especially useful when you need to perform side effects or asynchronous operations like API calls, where you need to dispatch actions based on the result of those calls. To understand thunks, it’s helpful to first know a bit about how Redux works:

Redux Basics:
1. Actions: In Redux, actions are plain JavaScript objects that describe “what happened”. They are the only source of information for the store.
2. Reducers: Reducers specify how the application’s state changes in response to actions. They are pure functions.

Asynchronous Operations in Redux:
- Redux itself is synchronous, meaning that reducers must be pure functions without side effects. This makes handling asynchronous operations (like fetching data from an API) directly within reducers impossible.

Enter Thunks:
- A thunk is a function that wraps an expression to delay its evaluation.
- In Redux, a thunk is a function that returns another function. This inner function takes two arguments: dispatch and getState.
- This allows the inner function to perform asynchronous tasks, dispatch actions, and access the current state.

How Thunks Work in Redux:
1. Dispatching a Thunk: You dispatch thunks just like regular actions, using the store.dispatch() method.
2. Handling Asynchronous Logic: The thunk can then perform some asynchronous operation (like an API call), and dispatch other actions based on the result or status of that operation.
3. Accessing Redux State: The thunk can also access the current state of the Redux store, allowing conditional logic based on the current state.

Example of a Thunk:
```javascript
const fetchUserData = (userId) => {
return (dispatch, getState) => {
dispatch({ type: ‘LOADING_USER_DATA’ });
fetch(/api/user/${userId})
.then(response => response.json())
.then(data => dispatch({ type: ‘USER_DATA_LOADED’, payload: data }))
.catch(error => dispatch({ type: ‘ERROR_LOADING_USER_DATA’, payload: error }));
};
};
~~~

In this example, fetchUserData is a thunk. When it’s dispatched, it starts an API request. Depending on the result of this request, it dispatches either a success action or an error action.

Why Use Thunks?
- Thunks provide a simple and consistent way to handle asynchronous logic and side effects in Redux applications.
- They allow for complex sequences of actions to be executed in a predictable manner.

Middleware:
- To enable thunks in a Redux application, you need to apply the redux-thunk middleware to your Redux store. This middleware allows thunks to intercept dispatched actions before they reach the reducer.

In summary, thunks in React Redux are used to handle complex synchronous or asynchronous logic that interacts with the Redux store, making it easier to manage side effects and asynchronous operations in Redux applications.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

What is jsx and how do browsers read it?

A

JSX (JavaScript XML) is an extension to the JavaScript language syntax. It looks similar to HTML or XML and is used predominantly with React to describe the structure of user interfaces. JSX is not natively understood by browsers and requires processing to be converted into standard JavaScript that browsers can interpret.

How JSX Works:
1. Syntax: JSX allows you to write HTML-like code in your JavaScript files. This makes the code for creating UI elements more readable and easier to write.

  1. Components: In React, JSX is used to render components. Components can be either simple HTML tags or user-defined components.
  2. Expressions: JSX allows you to embed JavaScript expressions within braces {}. This means you can use JavaScript variables, functions, and other features within your JSX code.

Example of JSX:
```jsx
const element = <h1>Hello, {name}</h1>;
~~~
Here, element is a JSX element. If name is a JavaScript variable, its value will be embedded into the rendered text.

Browser Compatibility:
- Browsers cannot read JSX directly since they are designed to interpret only JavaScript, HTML, and CSS.

Transformation Process:
1. Transpilation: Tools like Babel are used to transpile JSX code into standard JavaScript. Babel is a JavaScript compiler that converts next-generation JavaScript and JSX into older versions of JavaScript that browsers can understand.

  1. React.createElement(): During the transpilation process, Babel converts JSX elements into React.createElement() calls. This is how React understands and renders the components.

Transpiled JSX Example:
The above JSX element example would be transpiled into something like this:
```javascript
const element = React.createElement(‘h1’, null, ‘Hello, ‘, name);
~~~

Integration in Development Workflow:
- In a typical React development workflow, tools like Webpack or Parcel, along with Babel, are configured to automatically transpile JSX code into JavaScript as part of the build process. This build process generates JavaScript files that can be executed by the browser.

In summary, JSX is a syntax extension used in React for easier UI development. It must be transpiled into standard JavaScript for browsers to execute it, a process typically handled by development tools like Babel.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Name and explain the react lifecycle methods

A

React lifecycle methods are specific functions in a React class component that are executed at particular stages during the component’s life in the DOM. They provide hooks to perform actions at key moments in a component’s lifecycle, such as creation, updating, and destruction.

Mounting
These methods are called in the following order when an instance of a component is being created and inserted into the DOM:

  1. constructor(props)
    • Called before the component is mounted.
    • Used for initializing state and binding event handlers.
  2. static getDerivedStateFromProps(props, state)
    • Invoked right before rendering when new props or state are being received.
    • Returns an object to update the state, or null to update nothing.
  3. render()
    • The only required method in a class component.
    • Examines this.props and this.state and returns a React element, arrays and fragments, portals, string and numbers, Booleans or null.
  4. componentDidMount()
    • Invoked immediately after a component is mounted (inserted into the tree).
    • Good for initializing network requests, DOM operations, and setting up subscriptions.

Updating
An update can be caused by changes to props or state. These methods are called in the following order when a component is being re-rendered:

  1. static getDerivedStateFromProps(props, state)
    • Same as in mounting phase.
  2. shouldComponentUpdate(nextProps, nextState)
    • Lets React know if a component’s output is not affected by the current change in state or props.
    • Returns true by default. Returning false prevents the rendering.
  3. render()
    • Same as in mounting phase.
  4. getSnapshotBeforeUpdate(prevProps, prevState)
    • Called right before the most recently rendered output is committed to the DOM.
    • It enables the component to capture some information (e.g., scroll position) from the DOM before it is potentially changed.
  5. componentDidUpdate(prevProps, prevState, snapshot)
    • Invoked immediately after updating occurs (except for the initial render).
    • Good for DOM updates based on the new state and props.

Unmounting
This method is called when a component is being removed from the DOM:

  1. componentWillUnmount()
    • Invoked immediately before a component is unmounted and destroyed.
    • Useful for cleanup (e.g., invalidating timers, canceling network requests, or cleaning up subscriptions made in componentDidMount).

Error Handling
These methods are called when there is an error during rendering, in a lifecycle method, or in the constructor of any child component.

  1. static getDerivedStateFromError(error)
    • Used to render a fallback UI after an error is caught.
  2. componentDidCatch(error, info)
    • Used to log error information.

It’s important to note that these lifecycle methods are only available in class components. Functional components use hooks like useState and useEffect to handle the lifecycle in a different way.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

How are the lifecycle methods handled in function components?

A

In functional components in React, lifecycle methods are handled using React Hooks. Hooks are a feature introduced in React 16.8 that allow you to use state and other React features without writing a class. While class components use lifecycle methods like componentDidMount, componentDidUpdate, and componentWillUnmount, functional components achieve similar functionality through hooks like useState, useEffect, and others.

Common Hooks for Lifecycle Events:

  1. useState
    • Used for adding state to functional components.
    • Replaces this.state and this.setState in class components.
  2. useEffect
    • The primary hook for handling side effects, equivalent to componentDidMount, componentDidUpdate, and componentWillUnmount in class components.
    • It takes two arguments: a function to run for the effect and a dependency array.
    • ComponentDidMount: An effect that runs once after the initial rendering can be created by passing an empty dependency array [].
    • ComponentDidUpdate: To replicate componentDidUpdate, include values in the dependency array that, when changed, should trigger the effect.
    • ComponentWillUnmount: Cleanup logic can be executed by returning a function from the effect. This returned function will be called when the component is unmounted.
  3. useContext
    • Used for accessing the context in functional components.
    • Replaces the need for contextType or Consumer in class components.
  4. useReducer
    • An alternative to useState, ideal for managing more complex state logic.
    • Similar to how reducers work in Redux.
  5. useMemo and useCallback
    • useMemo is for memoizing values, to avoid expensive calculations on every render.
    • useCallback returns a memoized callback function. Useful for passing callbacks to optimized child components that rely on reference equality to prevent unnecessary renders.

Example Using useEffect:

```javascript
import React, { useState, useEffect } from ‘react’;

function ExampleComponent() {
const [count, setCount] = useState(0);

// Similar to componentDidMount and componentDidUpdate:
useEffect(() => {
    // Update the document title using the browser API
    document.title = `You clicked ${count} times`;

    // Similar to componentWillUnmount:
    return () => {
        // Any cleanup logic goes here.
    };
}, [count]); // Only re-run the effect if count changes

return (
    <div>
        <p>You clicked {count} times</p>
        <button onClick={() => setCount(count + 1)}>
            Click me
        </button>
    </div>
); } ~~~

In this example, useEffect is used to update the document title every time the count state changes, and it also includes cleanup logic (if any was needed).

React Hooks greatly simplify the handling of lifecycle events and state in functional components, making them more concise and easier to read compared to class components.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

How can we make a component re-render in react?

A

In React, a component re-renders when there is a change in its state or props. Here are various ways to trigger a re-render:

  1. Changing State:
    • Using the setState method in class components or the state update function from useState in functional components.
    • Example in a class component:
      javascript
      this.setState({ value: newValue });
    • Example in a functional component:
      javascript
      const [value, setValue] = useState(initialValue);
      setValue(newValue);
  2. Changing Props:
    • If a parent component changes the value of the props that it’s passing to a child component, the child component will re-render.
    • For example, changing a prop value in a parent component will cause all child components that receive that prop to re-render.
  3. Using the forceUpdate Method (Not Recommended):
    • Class components can use this.forceUpdate() to force a re-render. However, this is generally discouraged as it bypasses the component’s shouldComponentUpdate.
    • Example:
      javascript
      this.forceUpdate();
  4. Updating Context:
    • If a component consumes a React Context and the value of that context changes, the component will re-render.
  5. Using Hooks like useState or useReducer:
    • In functional components, changing state using hooks like useState or useReducer will cause a re-render.
    • Each call to the state setter function returned by useState or the dispatch function from useReducer will trigger a re-render.
  6. Parent Component Re-rendering:
    • A component will also re-render if its parent component re-renders, unless optimizations like React.memo for functional components or shouldComponentUpdate and PureComponent for class components are used.
  7. Key Prop:
    • Changing the key prop of a component causes it to unmount and remount, which is a form of re-rendering. This can be useful in certain scenarios but should be used judiciously.

Remember, excessive re-renders can lead to performance issues, so it’s important to manage state and props efficiently and use re-rendering strategies wisely. React’s reconciliation algorithm is quite efficient in handling re-renders, but as a developer, it’s crucial to understand and optimize component rendering behavior.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly