Home / Uncategorized / Uber NodeJS JavaScript and ReactJS interview questions answers

Uber NodeJS JavaScript and ReactJS interview questions answers

Deep Copy vs Shallow Copy

Shallow Copy

A shallow copy creates a new object with a new reference, but the properties of the new object refer to the same memory locations as the properties of the original object.

JavaScript Code Example:

const original = { a: 1, b: { c: 2 } };
const shallowCopy = { ...original };
shallowCopy.b.c = 3;

console.log(original.b.c);  // Output: 3 (Because the inner object is shared)

Deep Copy

A deep copy creates a new object and recursively copies all objects and arrays, ensuring no references to the original object.

JavaScript Code Example:

const original = { a: 1, b: { c: 2 } };
const deepCopy = JSON.parse(JSON.stringify(original));
deepCopy.b.c = 3;

console.log(original.b.c);  // Output: 2 (The inner object is not shared)

Deep Copy using a Custom Function

function deepCopy(obj) {
    return JSON.parse(JSON.stringify(obj));
}

const original = { a: 1, b: { c: 2 } };
const copy = deepCopy(original);
copy.b.c = 3;

console.log(original.b.c);  // Output: 2

Search Key-Value Pairs in Nested Object with Recursions

JavaScript Code Example:

function findValue(obj, keyToFind) {
    let result = null;

    function search(obj) {
        for (let key in obj) {
            if (key === keyToFind) {
                result = obj[key];
                return;
            }
            if (typeof obj[key] === 'object' && obj[key] !== null) {
                search(obj[key]);
            }
        }
    }

    search(obj);
    return result;
}

const data = { a: { b: { c: 1 } } };
console.log(findValue(data, 'c'));  // Output: 1

What is Currying Function?

Currying is a technique where a function returns another function that accepts one argument at a time.

JavaScript Code Example:

function multiply(a) {
    return function(b) {
        return function(c) {
            return a * b * c;
        };
    };
}

console.log(multiply(3)(2)(6));  // Output: 36

Prototype Inheritance and Keeping Child Prototype Intact

JavaScript Code Example:

function Parent() {
    this.parentProperty = 'parent';
}

Parent.prototype.parentMethod = function() {
    console.log('Parent method');
};

function Child() {
    Parent.call(this);
    this.childProperty = 'child';
}

// Set up inheritance
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;

Child.prototype.childMethod = function() {
    console.log('Child method');
};

const child = new Child();
child.parentMethod();  // Output: 'Parent method'
child.childMethod();   // Output: 'Child method'

Using Object.create ensures that the Child.prototype object correctly inherits from Parent.prototype.


Event Loop in Detail

The Event Loop is a mechanism that allows JavaScript to perform non-blocking operations by using a single-threaded model. It handles callbacks, promises, and other asynchronous operations.

Steps of the Event Loop:

  1. Execute Synchronous Code: Execute all the code that is present in the execution context.
  2. Check the Callbacks Queue: After executing the code, the event loop checks the callback queue (task queue) to see if there are any functions to run.
  3. Process the Callbacks: Process the functions from the callback queue.
  4. Check for Microtasks: Before moving to the next event loop iteration, it processes microtasks (promises).

Output Question Based on Event Loop

console.log(1);

setTimeout(() => { console.log(2) }, 0);

Promise.resolve().then(() => console.log(3));

Promise.resolve().then(() => setTimeout(() => { console.log(4) }, 0));

Promise.resolve().then(() => console.log(5));

setTimeout(() => { console.log(6) }, 0);

console.log(7);

Output:

  1. Synchronous Code: console.log(1) logs 1
  2. Microtasks: Promise.resolve().then(() => console.log(3)) logs 3
  3. Microtasks: Promise.resolve().then(() => console.log(5)) logs 5
  4. Microtasks: Promise.resolve().then(() => setTimeout(() => { console.log(4) }, 0)) is scheduled to run after the current microtasks
  5. Timeouts: setTimeout(() => { console.log(2) }, 0) and setTimeout(() => { console.log(6) }, 0) are scheduled to run in the next event loop iteration
  6. Synchronous Code: console.log(7) logs 7
  7. Next Microtasks: Logs 4 from the setTimeout wrapped in a Promise resolved
  8. Timeouts: Logs 2 and 6 from the setTimeout calls

Output Order:

1
7
3
5
2
6
4

React

Call Demo API and Filter List as We Type in Input Box

JavaScript Code Example (React):

import React, { useState, useEffect } from 'react';
import axios from 'axios';

const DemoComponent = () => {
    const [data, setData] = useState([]);
    const [query, setQuery] = useState('');
    const [filteredData, setFilteredData] = useState([]);

    useEffect(() => {
        async function fetchData() {
            const result = await axios('https://api.example.com/data');
            setData(result.data);
        }
        fetchData();
    }, []);

    useEffect(() => {
        setFilteredData(data.filter(item => item.name.toLowerCase().includes(query.toLowerCase())));
    }, [query, data]);

    return (
        <div>
            <input type="text" value={query} onChange={e => setQuery(e.target.value)} />
            <ul>
                {filteredData.map(item => (
                    <li key={item.id}>{item.name}</li>
                ))}
            </ul>
        </div>
    );
};

export default DemoComponent;

How to Optimize React and Above React Project

  1. Use Memoization: Use React.memo, useMemo, and useCallback to prevent unnecessary re-renders.
  2. Code Splitting: Dynamically import components to split code and improve load times.
  3. Virtualization: Use libraries like react-window for rendering large lists efficiently.
  4. Avoid Inline Functions: Move functions out of render methods to prevent creating new function instances.
  5. Optimize Dependencies: Ensure that useEffect and useCallback dependencies are well managed to avoid excessive re-renders.

JavaScript

How to Access DOM Elements in JS

JavaScript Code Example:

const elementById = document.getElementById('myId');
const elementByClassName = document.getElementsByClassName('myClass')[0];
const elementByTagName = document.getElementsByTagName('div')[0];
const elementByQuerySelector = document.querySelector('.myClass');
const elementsByQuerySelectorAll = document.querySelectorAll('.myClass');

What is Iframe

An <iframe> element allows you to embed another HTML document within the current document.

Example HTML Code:

<iframe src="https://www.example.com" width="600" height="400"></iframe>

How to Access an Element from Iframe

JavaScript Code Example:

const iframe = document.getElementById('myIframe');
const iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
const elementInIframe = iframeDocument.getElementById('elementId');

What is the Difference Between Window and Document

  • Window: Represents the browser window or tab, and has properties like alert, open, and location.
  • Document: Represents the HTML content of the window and has properties like getElementById, querySelector, and createElement.

What are Timers in JS

Timers are functions that allow you to execute code after a delay.

  • setTimeout(callback, delay): Executes callback after delay milliseconds.
  • setInterval(callback, interval): Repeatedly executes callback every interval milliseconds.

What is Promise in JS

A Promise represents a value that may be available now, or in the future, or never. It is a way to handle asynchronous operations.

JavaScript Code Example:

const promise = new Promise((resolve, reject) => {
    // Asynchronous operation
    if (true) {
        resolve('Success');
    } else {
        reject('Error');
    }
});

promise.then(result => console.log(result)).catch(error => console.log(error));

Certainly! Let’s dive into the details of deep cloning limitations using JSON.parse(JSON.stringify(obj)) and explore the concept of closures in JavaScript with an example.


Limitations of Deep Cloning Using JSON.parse(JSON.stringify(obj))

The JSON.parse(JSON.stringify(obj)) method is a common approach for deep cloning objects in JavaScript, but it has several limitations:

**1. *Date Objects are Lost*:

When you use JSON.stringify, Date objects are converted to strings. The resulting Date information is lost after parsing.

Example:

const original = { date: new Date() };
const clone = JSON.parse(JSON.stringify(original));

console.log(original.date);  // Output: Date object
console.log(clone.date);    // Output: String representation of the Date object
console.log(clone.date instanceof Date); // Output: false

**2. *Functions are Not Cloned*:

Functions cannot be cloned using JSON.stringify because functions are not supported in JSON format.

Example:

const original = { func: () => console.log('Hello') };
const clone = JSON.parse(JSON.stringify(original));

console.log(clone.func);  // Output: undefined

**3. *undefined, Infinity, and NaN Values are Ignored*:

These values are not represented in JSON, so they are lost in the cloning process.

Example:

const original = { a: undefined, b: Infinity, c: NaN };
const clone = JSON.parse(JSON.stringify(original));

console.log(clone.a);  // Output: undefined
console.log(clone.b);  // Output: null (because Infinity is not represented in JSON)
console.log(clone.c);  // Output: null (because NaN is not represented in JSON)

**4. *RegExp Objects are Lost*:

Regular expressions are not preserved through JSON.stringify.

Example:

const original = { regex: /test/ };
const clone = JSON.parse(JSON.stringify(original));

console.log(clone.regex);  // Output: undefined
console.log(clone.regex instanceof RegExp); // Output: false

**5. *Symbol Properties are Ignored*:

Properties keyed by Symbol are not included in the JSON representation.

Example:

const sym = Symbol('mySymbol');
const original = { [sym]: 'value' };
const clone = JSON.parse(JSON.stringify(original));

console.log(clone[sym]);  // Output: undefined

**6. *Circular References are Not Supported*:

JSON.stringify cannot handle objects with circular references.

Example:

const a = {};
a.b = a;

try {
    const clone = JSON.parse(JSON.stringify(a));
} catch (error) {
    console.error(error);  // Output: TypeError: Converting circular structure to JSON
}

**7. *Prototype Chain is Not Cloned*:

Only the properties of the object are cloned, not its prototype chain.

Example:

function MyClass() {
    this.name = 'example';
}
MyClass.prototype.greet = function() { return 'Hello'; };

const original = new MyClass();
const clone = JSON.parse(JSON.stringify(original));

console.log(clone.greet);  // Output: undefined

What is the Usage of Closure? Show an Example

What is a Closure?

A closure is a feature in JavaScript where an inner function retains access to the variables of its outer function even after the outer function has finished executing. This allows for the creation of private variables and functions, and it supports data encapsulation and function factories.

Usage of Closures

  1. Data Encapsulation: Protect data from being accessed directly from outside the function.
  2. Function Factories: Create functions with specific configurations.
  3. Maintaining State: Keep track of state across function calls.

Example of a Closure

1. Data Encapsulation Example:

function createCounter() {
    let count = 0;  // `count` is a private variable
    return function() {
        count++;
        return count;
    };
}

const counter = createCounter();
console.log(counter());  // Output: 1
console.log(counter());  // Output: 2
console.log(counter());  // Output: 3

In this example, count is a private variable that is only accessible through the returned inner function.

2. Function Factory Example:

function multiplyBy(factor) {
    return function(num) {
        return num * factor;
    };
}

const double = multiplyBy(2);
console.log(double(5));  // Output: 10

const triple = multiplyBy(3);
console.log(triple(5));  // Output: 15

Here, multiplyBy is a function factory that creates functions for multiplying numbers by a specific factor.

3. Maintaining State Example:

function createCounter(initialValue) {
    let count = initialValue;
    return {
        increment() {
            count++;
            return count;
        },
        decrement() {
            count--;
            return count;
        },
        getValue() {
            return count;
        }
    };
}

const myCounter = createCounter(10);
console.log(myCounter.getValue());  // Output: 10
console.log(myCounter.increment()); // Output: 11
console.log(myCounter.decrement()); // Output: 10

In this example, myCounter maintains the state of the count variable through multiple function calls.


Summary Table of Closures

FeatureDescriptionExample
Data EncapsulationHide private data from the outside worldconst counter = createCounter();
Function FactoryGenerate functions with customized behaviorconst double = multiplyBy(2);
Maintaining StatePreserve state between function callsconst myCounter = createCounter(10);

About Sushil Kumar

Check Also

Execute all the tasks in such a way that if there are no dependencies then the tasks can be started but if there are any dependencies then those tasks should execute once the dependency are completed. for the below tasks Object the output should be in the below way:-Input:-d-done b-done a-done c-done e-done

NodejsJavaScript const tasks = { 'd': ['b', 'c'], 'b': ['a'], 'a': [], 'c': [], 'e': …

Leave a Reply

Your email address will not be published. Required fields are marked *