main_bg

Unlocking JS: Some javaScript interview questions

Boost your JavaScript interview readiness with this collection of JavaScript interview questions and comprehensive answers. Deepen your understanding of JavaScript and be well-prepared for your next job interview in web development.

1. what is closure

ES5 has three kind of scope 1st global 2nd functional leval 3rd is closure. it says that variable created inside outer function can be used inside inner function.

Benefits:

  • we can create private variable by using it.
  • we can create closure for async methods if they are in loop.

Cons:

  • since scope of variable keeps alive they are not getting garbase collected so more memory uses will be there.

2. what variable and function hoisting, and what are differences between them.

variable defined or created anywhere in scope there definition goes on top is termed as variable hoisting.

function defined or created anywhere in scope there definition and implementation too goes on top is termed as function hoisting.

3. what is difference between var, let, const

var : used for variable creation and has only three scope global,functional, closure.

let : used for variable creation but its scope is valid inside block only variable created by using it can be registered for GC(garbage collection) after coming out of the block.

const : used for variable creation and is similar as final in java once initialised can not change its value.

4. what is difference between call, apply and bind

these all method are being used for attaching the context(value of this) but bind does not expect any argument where call expect object of argument and apply expect array of argument.

When I'm not having any argument I'll use bind. when I'm not certain for the length of argument I'll use apply else if I know all argument I'll use call.

5. what is promise.

- implement promise using es6 or es5.
- implement promise.all using es6 or es5.
- benefit of using promises over callback (what is callback hell)
- what is async await how to convert promise to async await, with try/catch block to handling errors as we have in catch method with promise.

6. Answer:

A promise is used to track a task which will execute in future and can go in two phases e.g. resolved/rejected

For other part search google.

7. what all http method are there and their significance

Get: It is being used to fetch the data. Post: We use it when we want to send some data to server and want something in return. Put: It is being just to put some data on server. delete: It is being used to delete some data on server. Option: For other purpose we use it like validating tokens etc.

Note: These are just for standards. We are not strictly bound to use them for given purpose.

8. what is the output of following code and how you will rectify it

for(var i = 0; i<100;i++){
    setTimeout(function(){
        console.log(i);
    },1000);
}

It will print 100 hundred times because loop will get executed initially and callback passed to setTimeout method will be pushed to the end of event loop. so they will executed when i will be already set to its limit i.e. 100

We can reactify it in following ways:

  • Using closure
    for(var i = 0; i<100;i++){
     (function(i){
         setTimeout(function(){
                console.log(i);
         },1000);
     })(i)
    }
    
  • Using let keyword ```javascript for(let i = 0; i<100;i++){ setTimeout(function(){
      console.log(i);
    
    },1000); }

- Using call/apply
 ```javascript
    // search google

9. what is major difference between ECMA5 and ECMA6

See link (http://es6-features.org/#Constants)

Classes, Arrow Functions, Block Scope using let keyword, Promises etc

10. what is ECMA

ECMA is an organisation which standardise javascript.

11. Why javascript is your favorite language

It is my favorite language because of its simplicity and diversity to use. If I know javascript I can work on any part of application Front-End(react, angular etc.), TDD testing(kerma, mocha, chai), BDD testing(protractor), backend or micro-services using nodeJS, DataBase in MongoDB, IOT or embeded system using jerryscript etc.

12. what is callback hell and how you will remove it

long or iterative nesting of asynchronous functions is known as callback hell.

We can remove it in two ways:

  • By using promises
  • By using async await

13. what is anonymous functions?

An anonymous function is a function without a name. It is defined on the fly, often used for short, one-time operations. In JavaScript, you can create anonymous functions using the function keyword without assigning a name.

14. what is prototype

n JavaScript, a prototype is an object from which other objects inherit properties and methods. It serves as a template or blueprint for creating objects with shared characteristics. Objects in JavaScript have an implicit reference to their prototype, and when a property or method is accessed on an object, JavaScript looks for it in the object's prototype chain if it's not found directly on the object. The prototype mechanism enables the concept of prototypal inheritance, allowing objects to inherit and share behavior.

15. What all ways we can implement OOPS(Object Oriented Programming System) like inheritance, encapsulation, Polymorphism, abstraction. what is prototypical inheritance

In JavaScript, which is a prototype-based language, you can implement Object-Oriented Programming (OOP) principles such as inheritance, encapsulation, polymorphism, and abstraction. Here's a brief explanation of each with examples:

16. Inheritance:

  • Definition: Inheritance is the ability of a class (or object) to inherit properties and methods from another class (or object).

  • Example:

    javascript
    // Parent class function Animal(name) { this.name = name; } // Child class inheriting from Animal function Dog(name, breed) { Animal.call(this, name); // Call the constructor of the parent class this.breed = breed; } // Creating an instance of the child class const myDog = new Dog('Buddy', 'Labrador'); console.log(myDog.name); // Accessing property from the parent class

17. Encapsulation:

  • Definition: Encapsulation is the bundling of data and methods that operate on the data into a single unit, restricting access to some of the object's components.

  • Example:

    javascript
    // Using closures for encapsulation function Counter() { let count = 0; // Private variable return { increment: function() { count++; }, getCount: function() { return count; } }; } const myCounter = Counter(); myCounter.increment(); console.log(myCounter.getCount()); // Accessing data through methods

18. Polymorphism:

  • Definition: Polymorphism allows objects of different types to be treated as objects of a common type, enabling flexibility and extensibility.

  • Example:

    javascript
    // Polymorphic function function printInfo(animal) { console.log(`Name: ${animal.name}`); if (animal.speak) { animal.speak(); } } // Objects with a common interface const cat = { name: 'Whiskers', speak: function() { console.log('Meow'); } }; const dog = { name: 'Buddy', speak: function() { console.log('Woof'); } }; printInfo(cat); printInfo(dog);

19. Abstraction:

  • Definition: Abstraction is the process of simplifying complex systems by modeling classes based on essential properties and behaviors.

  • Example:

    javascript
    // Abstracting a Shape class class Shape { constructor(color) { this.color = color; } // Abstract method draw() { throw new Error('Abstract method - implement in subclasses'); } } // Concrete implementation class Circle extends Shape { constructor(color, radius) { super(color); this.radius = radius; } draw() { console.log(`Drawing a ${this.color} circle with radius ${this.radius}`); } } const myCircle = new Circle('red', 5); myCircle.draw();

These examples illustrate how you can implement OOP principles in JavaScript. It's important to note that JavaScript's approach to OOP is prototype-based, and the language provides flexibility in achieving OOP concepts. ES6 and later versions have introduced class syntax, making it more familiar to developers coming from class-based languages.

20. what is prototype chain

In JavaScript, the prototype chain is a mechanism that allows objects to inherit properties and methods from other objects through their prototype. Each object in JavaScript has an implicit reference to its prototype, forming a chain of objects linked together. When you access a property or method on an object, and if it's not found directly on the object, JavaScript looks for it in the object's prototype, and this process continues up the prototype chain until the property or method is found or the chain reaches the end.

Here's a basic explanation of the prototype chain:

  • Objects and Prototypes:

    • Every object in JavaScript is associated with a prototype object.
    • The prototype object is another object that the current object inherits from.
  • Accessing Properties and Methods:

    • When you try to access a property or method on an object, JavaScript checks if the object has that property or method.
    • If the property or method is not found on the object, JavaScript looks for it in the object's prototype.
  • Chain of Inheritance:

    • If the property or method is not found in the immediate prototype, JavaScript continues searching up the prototype chain.
    • This forms a chain of objects linked by their prototypes.
  • Prototype of Prototypes:

    • The process continues until the end of the prototype chain, where the last prototype typically has a null prototype.
    • If the property or method is not found anywhere in the prototype chain, JavaScript returns undefined.

Here's a simple example to illustrate the prototype chain:

javascript
// Parent object const animal = { eat: function() { console.log('Eating...'); } }; // Child object inheriting from the parent const dog = Object.create(animal); dog.bark = function() { console.log('Barking...'); }; // Grandchild object inheriting from the dog const puppy = Object.create(dog); puppy.wagTail = function() { console.log('Wagging tail...'); }; // Accessing properties/methods along the prototype chain puppy.wagTail(); // Found on puppy puppy.bark(); // Found on dog (inherited from animal) puppy.eat(); // Found on animal (inherited from Object.prototype)

In this example, puppy inherits from dog, which in turn inherits from animal, forming a prototype chain. The Object.create() method is used to create objects with a specified prototype.

21. what is difference between arrow functions and normal/regular functions

Arrow functions and regular (or normal) functions in JavaScript have some key differences in terms of syntax, behavior, and the handling of the this keyword. Here are the main distinctions:

22. Syntax:

  • Arrow Function:
    javascript
    const add = (a, b) => a + b;
  • Regular Function:
    javascript
    function add(a, b) { return a + b; }

23. this Binding:

  • Arrow Function:
    • Arrow functions do not have their own this context. They inherit the this value from the enclosing scope (lexical scoping).
    • This behavior can be advantageous in certain scenarios, especially when dealing with callbacks and maintaining the context.
  • Regular Function:
    • Regular functions have their own this context, which is dynamically determined at runtime based on how the function is called.
    • The this value in a regular function is influenced by how the function is invoked, such as with methods, constructors, or standalone function calls.

24. Arguments Object:

  • Arrow Function:
    • Arrow functions do not have their own arguments object. If you need to access arguments, you would use the arguments object of the enclosing scope.
  • Regular Function:
    • Regular functions have their own arguments object, which contains all the arguments passed to the function.

25. new Keyword:

  • Arrow Function:
    • Arrow functions cannot be used as constructors. They cannot be invoked with the new keyword to create instances.
  • Regular Function:
    • Regular functions can be used as constructors when invoked with the new keyword, allowing the creation of new objects.

26. prototype Property:

  • Arrow Function:
    • Arrow functions do not have a prototype property. They cannot be used as constructors, so there is no prototype for instances.
  • Regular Function:
    • Regular functions have a prototype property, which is used when creating instances with the new keyword. Instances inherit properties and methods from the prototype.

27. Example:

Here's a practical example demonstrating the this behavior:

javascript
const obj = { value: 42, getValueArrow: () => this.value, getValueRegular: function() { return this.value; } }; console.log(obj.getValueArrow()); // undefined (lexical scoping) console.log(obj.getValueRegular()); // 42 (this is obj)

In the arrow function getValueArrow, this refers to the global object or undefined (in strict mode) because arrow functions do not bind their own this. In contrast, the regular function getValueRegular correctly refers to the value property of the obj.

In summary, the choice between arrow functions and regular functions depends on the specific use case, especially when considering the handling of this and other factors. Arrow functions are concise and often preferred for short, simple functions, while regular functions provide more flexibility and are suitable for a wider range of scenarios.

28. what is difference between function expression and function keyword

The terms "function expression" and "function keyword" refer to different ways of defining functions in JavaScript. Here are the key differences:

29. Function Expression:

  • In a function expression, a function is assigned to a variable. It's a type of variable assignment where the function is part of an expression.
  • Function expressions are often used for anonymous functions or when a function is only needed in a specific context.
  • Example:
    javascript
    const add = function(a, b) { return a + b; };

30. Function Keyword:

  • The "function keyword" typically refers to the traditional way of defining a function using the function keyword followed by the function name and a block of code.
  • Function declarations using the function keyword are hoisted, meaning they are moved to the top of their scope during the compilation phase.
  • Example:
    javascript
    function add(a, b) { return a + b; }

31. Key Differences:

  • Hoisting:

    • Function expressions are not hoisted. They are only available in the code after the point of declaration.
    • Function declarations using the function keyword are hoisted, meaning they can be used in the code before the declaration.
  • Anonymous vs Named:

    • Function expressions can be anonymous (no function name) or named.
    • Function declarations using the function keyword are named by default, but they can also be anonymous.
  • Usage:

    • Function expressions are often used when a function is assigned to a variable, passed as an argument, or used in a specific context.
    • Function declarations are typically used when you need the function to be available throughout the scope, and you want it to be hoisted.
  • Hoisting Order:

    • The assignment part of a function expression is not hoisted, only the variable declaration is hoisted.
    • The entire function declaration (including its body) is hoisted.

32. implement promise, apply, call, bind using es5 (Very important for senior software engineer)

In ES5 (ECMAScript 5), which is the version of JavaScript released in 2009, Promise, apply, call, and bind were not native features. However, you can create your own implementations for some of these functionalities. Note that the examples provided here are simplified and might not cover all the edge cases handled by the native implementations in modern JavaScript.

33. Promise (Deferred Pattern):

javascript
function MyPromise() { this.state = 'pending'; this.value = undefined; this.callbacks = []; this.resolve = function(value) { if (this.state === 'pending') { this.state = 'fulfilled'; this.value = value; this.callbacks.forEach(callback => callback.onFulfilled(value)); } }; this.reject = function(reason) { if (this.state === 'pending') { this.state = 'rejected'; this.value = reason; this.callbacks.forEach(callback => callback.onRejected(reason)); } }; this.then = function(onFulfilled, onRejected) { return new MyPromise((resolve, reject) => { if (this.state === 'fulfilled') { setTimeout(() => { try { const result = onFulfilled(this.value); resolve(result); } catch (error) { reject(error); } }, 0); } else if (this.state === 'rejected') { setTimeout(() => { try { const result = onRejected(this.value); resolve(result); } catch (error) { reject(error); } }, 0); } else { this.callbacks.push({ onFulfilled, onRejected, resolve, reject }); } }); }; } // Example usage: const promise = new MyPromise((resolve, reject) => { setTimeout(() => { resolve('Success!'); // or // reject('Failure!'); }, 1000); }); promise.then( result => console.log('Fulfilled:', result), error => console.error('Rejected:', error) );

34. apply, call, bind:

In ES5, you can implement basic versions of apply, call, and bind as follows:

javascript
// Polyfill for Function.prototype.apply Function.prototype.myApply = function(context, argsArray) { context = context || global; // global object if context is undefined or null context.__fn = this; const result = context.__fn(...argsArray); delete context.__fn; return result; }; // Polyfill for Function.prototype.call Function.prototype.myCall = function(context, ...args) { context = context || global; context.__fn = this; const result = context.__fn(...args); delete context.__fn; return result; }; // Polyfill for Function.prototype.bind Function.prototype.myBind = function(context) { const fn = this; const args = Array.prototype.slice.call(arguments, 1); return function() { const bindArgs = Array.prototype.slice.call(arguments); return fn.apply(context, args.concat(bindArgs)); }; }; // Example usage: function greet(greeting) { console.log(`${greeting}, ${this.name}!`); } const person = { name: 'John' }; greet.myApply(person, ['Hello']); // Output: Hello, John! greet.myCall(person, 'Hi'); // Output: Hi, John! const boundGreet = greet.myBind(person, 'Hola'); boundGreet(); // Output: Hola, John!

Keep in mind that these implementations are basic and may not cover all edge cases and features of the native implementations in modern JavaScript. For production use, it is recommended to use the native methods or consider using a transpiler like Babel to write modern JavaScript code that can be transpiled to ES5 for wider compatibility.

35. what is rest parameters

Rest parameters in JavaScript allow you to represent an indefinite number of arguments as an array. They are introduced using the ellipsis (...) followed by a parameter name, and they gather the remaining arguments passed to a function into an array. Rest parameters provide a concise way to work with variable-length argument lists.

Here's a basic syntax example:

javascript
function sum(...numbers) { return numbers.reduce((acc, num) => acc + num, 0); } console.log(sum(1, 2, 3, 4, 5)); // Output: 15

In this example, the sum function takes any number of arguments and uses the rest parameter ...numbers to gather them into an array called numbers. The function then uses the reduce method to calculate the sum of all the numbers in the array.

Key points about rest parameters:

  • Syntax:

    • Rest parameters are indicated by the use of the ellipsis (...) followed by a parameter name.
    • The rest parameter must be the last parameter in the function's parameter list.
  • Array Representation:

    • The rest parameter collects the remaining arguments into an array.
  • No Need for arguments Object:

    • Rest parameters provide a more convenient and modern alternative to using the arguments object, which is an array-like object available in all function scopes that holds all passed arguments.
  • Use Cases:

    • Useful when dealing with functions that accept a variable number of arguments.
    • Simplifies handling variable-length argument lists without explicitly specifying each parameter.
  • Example with Regular Parameters:

    javascript
    function example(a, b, ...rest) { console.log(`a: ${a}`); console.log(`b: ${b}`); console.log(`rest: ${rest}`); } example(1, 2, 3, 4, 5); // Output: // a: 1 // b: 2 // rest: 3,4,5

Rest parameters are widely used in modern JavaScript to enhance the flexibility and readability of functions that work with variable-length argument lists. They are especially handy when dealing with functions where the number of arguments may vary.

36. what is destructuring in javascript

Destructuring in JavaScript is a concise and flexible syntax that allows you to extract values from arrays or properties from objects and assign them to variables. It provides a more convenient way to work with structured data, making code shorter and more readable.

37. Array Destructuring:

With array destructuring, you can extract values from an array and assign them to variables in a single statement:

javascript
// Example 1 const numbers = [1, 2, 3]; const [a, b, c] = numbers; console.log(a, b, c); // Output: 1 2 3 // Example 2: Skipping values const [first, , third] = numbers; console.log(first, third); // Output: 1 3

38. Object Destructuring:

With object destructuring, you can extract values from an object and assign them to variables with matching property names:

javascript
// Example 1 const person = { name: 'John', age: 30, city: 'New York' }; const { name, age, city } = person; console.log(name, age, city); // Output: John 30 New York // Example 2: Assigning to new variable names const { name: fullName, age: years, city: residence } = person; console.log(fullName, years, residence); // Output: John 30 New York

39. Default Values:

You can also provide default values for variables in case the value is not present:

javascript
const colors = ['red', 'green']; const [primary = 'blue', secondary = 'yellow', tertiary = 'purple'] = colors; console.log(primary, secondary, tertiary); // Output: red green purple

40. Nested Destructuring:

Destructuring can be nested for more complex data structures:

javascript
const person = { name: 'John', age: 30, address: { city: 'New York', zip: '10001' } }; const { name, address: { city } } = person; console.log(name, city); // Output: John New York

41. Function Parameter Destructuring:

You can use destructuring in function parameters:

javascript
function printPerson({ name, age }) { console.log(`Name: ${name}, Age: ${age}`); } const person = { name: 'Alice', age: 25 }; printPerson(person); // Output: Name: Alice, Age: 25

Destructuring simplifies code, especially when working with complex data structures, and is widely used in modern JavaScript to make code more readable and maintainable. It's supported in ES6 (ECMAScript 2015) and later versions of JavaScript.

42. what are generator functions in javascript (Only asked if technical architect of higher position)

Generator functions in JavaScript are a special type of function that can be paused and resumed, allowing you to control the flow of execution manually. They are defined using the function* syntax and use the yield keyword to produce a sequence of values lazily.

Here is a basic example of a generator function:

javascript
function* simpleGenerator() { yield 1; yield 2; yield 3; } const generator = simpleGenerator(); console.log(generator.next()); // { value: 1, done: false } console.log(generator.next()); // { value: 2, done: false } console.log(generator.next()); // { value: 3, done: false } console.log(generator.next()); // { value: undefined, done: true }

In this example, the simpleGenerator function, when invoked, returns a generator object. The next method of the generator is used to advance its execution until the next yield statement is encountered. The result of each yield statement is an object with a value property and a done property indicating whether the generator has finished.

Key features of generator functions:

  • Pausing and Resuming:

    • Generator functions can be paused at a yield statement, allowing you to control the flow of execution.
  • Lazy Execution:

    • Values are produced lazily. The generator only computes the next value when requested through the next method.
  • Stateful:

    • Generator functions maintain their internal state between calls to next, allowing them to remember their position.
  • Infinite Sequences:

    • Generator functions can be used to represent infinite sequences of values because they generate values on demand.

Here's an example of an infinite sequence generator:

javascript
function* infiniteSequence() { let i = 0; while (true) { yield i++; } } const generator = infiniteSequence(); console.log(generator.next().value); // 0 console.log(generator.next().value); // 1 console.log(generator.next().value); // 2 // ...

Generators are commonly used in asynchronous programming, such as with the async/await syntax, to simplify asynchronous code and make it look more synchronous.

javascript
async function fetchData() { const data1 = await fetchData1(); const data2 = await fetchData2(); return [data1, data2]; }

Generator functions provide a more manual approach to achieving similar results. They offer a powerful tool for creating iterators and handling asynchronous code with a more explicit control flow.

43. implement Array.concat, Array.forEach, Array.map, Array.flat using es5

Note that these implementations are simplified and may not cover all edge cases handled by the native Array methods in modern JavaScript.

44. Array.concat:

javascript
function concat() { var result = []; for (var i = 0; i < arguments.length; i++) { if (Array.isArray(arguments[i])) { for (var j = 0; j < arguments[i].length; j++) { result.push(arguments[i][j]); } } else { result.push(arguments[i]); } } return result; } // Example var arr1 = [1, 2]; var arr2 = [3, 4]; var combined = concat(arr1, arr2, 5, [6]); console.log(combined); // [1, 2, 3, 4, 5, 6]

45. Array.forEach:

javascript
function forEach(arr, callback) { for (var i = 0; i < arr.length; i++) { callback(arr[i], i, arr); } } // Example var numbers = [1, 2, 3]; forEach(numbers, function (value, index) { console.log(value, index); });

46. Array.map:

javascript
function map(arr, callback) { var result = []; for (var i = 0; i < arr.length; i++) { result.push(callback(arr[i], i, arr)); } return result; } // Example var numbers = [1, 2, 3]; var squared = map(numbers, function (value) { return value * value; }); console.log(squared); // [1, 4, 9]

47. Array.flat:

javascript
function flat(arr, depth) { var result = []; depth = depth || 1; function flatten(input, currentDepth) { for (var i = 0; i < input.length; i++) { if (Array.isArray(input[i]) && currentDepth < depth) { flatten(input[i], currentDepth + 1); } else { result.push(input[i]); } } } flatten(arr, 0); return result; } // Example var nestedArray = [1, [2, [3, 4]]]; var flattenedArray = flat(nestedArray, 2); console.log(flattenedArray); // [1, 2, [3, 4]]

Please note that these implementations are simplified and may not cover all the edge cases handled by the native Array methods in modern JavaScript. Also, the Array.flat implementation is basic and only supports a specified depth. The native Array.flat method in modern JavaScript supports flatting to any depth with the use of Infinity.

48. Algorithmic question

- Find string is palindrome or not

49. - Find number is a prime number or not

- Render Pyramid of * e.g. Sample

50. - Find no of island e.g. Sample

Do it by yourself, for practice

51. - Flatten array without using Array.prototype.flat

Do it by yourself, for practice

52. - Find second-highest number in array of sorted and un sorted array (Optimise way)

Do it by yourself, for practice

53. - Find word with second-highest frequency in a paragraph

Do it by yourself, for practice

54. - Split word with vowels with and without using regular expression

Do it by yourself, for practice

55. - There are some petrol pump in circle. They have Total fuel to just cover round journey by a vehicle.

Where should vehicle start trip so he can complete whole circle from start.
Write a programme for it.

56. - Find pairs of number from given array whose sum is 10.

- Find Pairs: Sample

57. What is the difference between local storage, cookies and session storage? where you use what.

Local Storage, Cookies, and Session Storage are three commonly used client-side storage mechanisms in web development, each serving specific purposes. Here's a comparison of these storage options:

58. Local Storage:

  • Capacity:

    • Size: Up to 5 MB per domain.
    • Scope: Persistent across browser sessions.
  • Lifetime:

    • Persistence: Data persists even when the browser is closed and reopened.
  • Scope:

    • Global: Data is accessible across browser tabs and windows for the same domain.
  • Use Cases:

    • Storing preferences and settings.
    • Caching static assets for faster page loading.
    • Long-term data storage.

59. Session Storage:

  • Capacity:

    • Size: Up to 5 MB per domain.
    • Scope: Limited to the duration of the page session.
  • Lifetime:

    • Persistence: Data is cleared when the browser session ends (when the browser or tab is closed).
  • Scope:

    • Local: Data is accessible only within the same tab or window.
  • Use Cases:

    • Storing temporary data needed for a single session.
    • Implementing features that require data to be available only while the user is on the page.

60. Cookies:

  • Capacity:

    • Size: Up to 4 KB per domain.
    • Scope: Varies (can be domain-wide or path-specific).
  • Lifetime:

    • Persistence: Depends on the expiration time set for the cookie.
  • Scope:

    • Varying: Can be domain-wide or restricted to a specific path.
  • Use Cases:

    • Storing user authentication tokens.
    • Tracking user preferences.
    • Implementing features with server-side access to stored data.

61. Other Client-Side Storage Options:

  • IndexedDB:

    • A low-level API for storing large amounts of structured data. It offers a more powerful and flexible solution but has a steeper learning curve.
  • Web SQL Database (deprecated):

    • A relational database API that is now deprecated and not recommended for use in new projects.

62. When to Use What:

  • Local Storage:

    • Use for long-term storage.
    • When you need to persist data across browser sessions.
    • For preferences and settings.
  • Session Storage:

    • Use for short-term storage.
    • When data is only needed for the duration of a single page session.
    • For temporary data that can be discarded when the user closes the tab or window.
  • Cookies:

    • Use when server-side access to data is required.
    • For small amounts of data needed for both short-term and long-term use.
    • When data needs to be sent to the server with each HTTP request.
  • IndexedDB:

    • Use for storing large amounts of structured data.
    • When a more powerful, asynchronous storage solution is needed.

It's essential to consider factors such as data size, persistence requirements, and accessibility scope when choosing a client-side storage solution for a specific use case. In many scenarios, developers use a combination of these storage options based on their specific needs.

63. what is JWT tokens. Benefits of using JWT tokens over session. What is best place to store JWT tokens, or secure items.

JWT (JSON Web Token):

JWT, or JSON Web Token, is a compact, URL-safe means of representing claims between two parties. It is often used for authentication and information exchange in web development. JWTs consist of three parts: a header, a payload, and a signature. These parts are encoded and concatenated to form the token.

64. Benefits of Using JWT Tokens Over Session:

  • Stateless:

    • JWTs are stateless, meaning the server does not need to store the token's state. This allows for easy horizontal scaling and reduces the need for server-side storage.
  • Compact and Efficient:

    • JWTs are compact and can be easily transmitted over the network. This is particularly advantageous in scenarios where bandwidth is a concern.
  • Decentralized Authentication:

    • JWTs allow for decentralized authentication, meaning that different services or microservices can issue and verify JWTs independently.
  • Claims and Information:

    • JWTs can contain claims (pieces of information) that can be used to convey user roles, permissions, and other details. This reduces the need for additional server-side queries.
  • Standardized Format:

    • JWTs follow a standardized format, making them interoperable across different systems and programming languages.
  • Cross-Domain Usage:

    • JWTs can be used in cross-domain scenarios, facilitating single sign-on (SSO) between different applications.

65. Best Place to Store JWT Tokens or Secure Items:

  • HTTP Only Cookies:

    • Storing JWTs in HTTP-only cookies adds an additional layer of security by preventing client-side JavaScript from accessing the token directly. This helps mitigate certain types of attacks, such as Cross-Site Scripting (XSS).
  • Secure and HttpOnly Flags:

    • Ensure that the cookie is marked as "Secure" to only transmit over HTTPS, and use the "HttpOnly" flag to prevent client-side access.
  • Token Expiry and Refresh Tokens:

    • Include an expiration time in the JWT payload and implement token refreshing. This helps mitigate the risk of long-lived tokens.
  • Secure Storage Mechanisms:

    • If not using cookies, store JWTs securely in a client-side storage mechanism, such as Web Storage (localStorage or sessionStorage). However, be cautious of XSS attacks in this scenario.
  • Use HTTPS:

    • Ensure that your application uses HTTPS to encrypt data in transit, preventing eavesdropping and man-in-the-middle attacks.
  • Token Blacklisting:

    • Implement token blacklisting to invalidate compromised tokens. This can be done by maintaining a list of revoked or expired tokens on the server.

66. Considerations:

  • Sensitive Information:

    • Avoid storing sensitive information in the JWT payload as it is visible to the client.
  • Token Revocation:

    • Implement a mechanism for token revocation in case a token needs to be invalidated before its expiration time.
  • Encryption:

    • For additional security, consider encrypting JWTs if the information they carry needs to be confidential.

By following best practices for storing and securing JWTs, developers can harness the benefits of this token-based authentication approach while maintaining a high level of security.

67. what will be output of following:

concept of variable hoisting
var x = 5;
console.log(x);
function a() {
    console.log(x);
    var x = 6;
    console.log(x);
    return x;
}
console.log(x)
console.log(a())

do by yourself

68. concept of use strict

'use strict';
var x = 5;
console.log(x);
function a() {
    console.log(x);
    var x = 6;
    console.log(x);
    return x;
}
console.log(x)
console.log(a())

69. Concept of this

console.log(this);
[5].forEach((i) => {
    console.log(this.length);
})
[5].forEach(function (i) {
    console.log(this.length);
})
var a = {
    x1: () => {
        console.log(this);
    },
    x2: function () {
        console.log(this);
    }
}
a.x1();

var temp = () => {
    this.x1();
}
temp();
temp.apply(a, [])

var temp1 = () => {
    this.x1();
}
temp1 = temp1.bind(a);
temp1()

70. what is lexical scope/environment

Lexical scope, also known as static scope, is a concept in programming languages, including JavaScript, that describes how the scope of variables is determined at the time of lexical (static) analysis, i.e., during the creation of the code, rather than at runtime. Lexical scope is defined by the physical structure of the code and the placement of variables and blocks within the code.

In lexical scope:

  • Scope Hierarchy:

    • Variables are defined within blocks, functions, or the global scope.
    • The scope of a variable is determined by its location in the source code.
  • Access to Variables:

    • Inner blocks or functions can access variables defined in their containing (outer) blocks or functions.
    • Variables are accessible both upward and downward in the scope chain.

Here's an example in JavaScript:

javascript
function outer() { const outerVar = 'I am from outer'; function inner() { const innerVar = 'I am from inner'; console.log(outerVar); // Accessing outerVar from the outer scope console.log(innerVar); // Accessing innerVar from the same scope } inner(); } outer();

In this example, inner has access to both outerVar and innerVar. The scope of outerVar extends to the inner function because of lexical scoping.

71. Lexical Environment:

The lexical environment is a structure that holds identifier-variable mapping, and it is created during the lexical phase of code execution. It consists of two components:

  • Environment Record:

    • A data structure that maps identifier names to variable values.
  • Reference to the Outer Environment:

    • A reference to the lexical environment of the containing (outer) scope.

The lexical environment helps determine the value of a variable when it's accessed in the code.

javascript
function outer() { const outerVar = 'I am from outer'; function inner() { const innerVar = 'I am from inner'; console.log(outerVar); } inner(); } outer();

In this example, the lexical environment of inner includes an environment record with mappings for innerVar and a reference to the lexical environment of outer. This reference allows inner to access variables from the outer scope, creating a chain of lexical environments.

In summary, lexical scope is a fundamental concept that influences how variables are accessed and resolved in a programming language. It is based on the physical structure of the code and determines the scope of variables at compile time. Lexical scope is used in many modern programming languages to provide clear rules for variable resolution and scoping.

72. What are polyfills.

Polyfills are code snippets or scripts that provide modern functionality to older browsers that lack support for certain features or APIs. The term "polyfill" is a combination of "poly," meaning many, and "fill," implying the filling of gaps or adding missing functionality. Polyfills are often used to bridge the compatibility gap between older browsers and the latest web standards.

Here's how polyfills work and why they are important:

73. How Polyfills Work:

  • Feature Detection:

    • Polyfills often start by checking if a particular feature or API is supported in the user's browser.
    • Modern web development practices typically involve feature detection to determine whether a browser supports a specific functionality.
  • Conditional Loading:

    • If the feature is not supported, the polyfill script is loaded conditionally, injecting the missing functionality into the browser.
    • If the feature is supported, the polyfill may not be loaded, reducing unnecessary overhead.
  • Providing Missing Functionality:

    • The polyfill script contains JavaScript code that emulates the desired functionality or implements missing APIs using standard web technologies.
  • Enhancing Cross-Browser Compatibility:

    • Polyfills enhance cross-browser compatibility by enabling developers to use the latest web features while ensuring that their applications still function on older browsers.

74. Why Polyfills are Important:

  • Support for New Web Standards:

    • Browsers evolve, and new web standards are introduced. Polyfills allow developers to use these standards without worrying about lack of support in older browsers.
  • Progressive Enhancement:

    • Developers can build applications with the latest features and progressively enhance them with polyfills to ensure a consistent experience across various browsers.
  • Reduced Fragmentation:

    • Polyfills help reduce browser fragmentation by enabling developers to write code that works uniformly across different browsers, regardless of their version.
  • Maintainability:

    • Using polyfills can simplify code maintenance by allowing developers to adopt new features without writing complex browser-specific code.

75. what is v8 engine

The V8 engine is an open-source JavaScript engine developed by Google. It is primarily used in the Google Chrome web browser but is also employed in various other projects and applications, including Node.js. V8 is designed to execute JavaScript code and provides a high-performance runtime environment.

76. V8 Engine Architecture:

The architecture of the V8 engine consists of several components that work together to parse, compile, optimize, and execute JavaScript code efficiently. Here are the key components of the V8 engine architecture:

  • Parser:

    • The parser reads and interprets the JavaScript source code, converting it into an Abstract Syntax Tree (AST).
  • Ignition Interpreter:

    • The Ignition interpreter is a lightweight JavaScript interpreter. It quickly translates the AST into bytecode, a lower-level representation of the code.
  • TurboFan Compiler:

    • The TurboFan compiler is responsible for generating highly optimized machine code from the bytecode produced by the Ignition interpreter.
    • TurboFan performs various optimization techniques, including inlining functions, loop unrolling, and type specialization, to produce efficient machine code.
  • Garbage Collector:

    • V8 includes a garbage collector to manage memory. The garbage collector automatically identifies and reclaims memory that is no longer in use, helping to prevent memory leaks.
  • Profiler:

    • The profiler collects runtime information about the execution of JavaScript code. This information is used to identify hot functions and improve optimization decisions.
  • Heap and Stack:

    • The memory in V8 is organized into a heap and a stack. The heap stores objects dynamically allocated during program execution, while the stack is used for function calls and local variables.
  • Execution Pipeline:

    • The overall execution pipeline involves parsing the JavaScript source code, generating bytecode, interpreting bytecode with Ignition, and optimizing critical parts of the code with TurboFan.

77. Execution Flow:

  • Parsing:

    • The JavaScript source code is parsed into an Abstract Syntax Tree (AST).
  • Ignition (Interpreter):

    • The Ignition interpreter quickly translates the AST into bytecode.
  • Execution:

    • The bytecode is executed by the Ignition interpreter for quick start-up performance.
  • Profiling:

    • Profiling information is collected during execution.
  • Optimization:

    • The TurboFan compiler uses profiling information to generate highly optimized machine code.
  • Garbage Collection:

    • The garbage collector manages memory, reclaiming unused memory to prevent leaks.

78. Characteristics:

  • Just-In-Time (JIT) Compilation:

    • V8 uses a combination of interpreting and just-in-time (JIT) compilation to execute JavaScript code efficiently.
  • Optimization Techniques:

    • TurboFan employs advanced optimization techniques to generate highly optimized machine code, adapting to the runtime characteristics of the code.
  • Concurrency:

    • V8 is designed to execute JavaScript code concurrently, leveraging multiple CPU cores for improved performance.

Understanding the architecture of the V8 engine is crucial for developers working with JavaScript, especially when optimizing code for better performance in web applications or server-side environments using Node.js.

79. what all javascript engines are their in market and which all browsers use them.

Several JavaScript engines are used by different web browsers to interpret and execute JavaScript code. Here are some prominent JavaScript engines and the browsers that use them:

  • V8 (Google Chrome, Node.js):

    • Browsers: Google Chrome, Chromium-based browsers (e.g., Microsoft Edge, Opera, Brave).
    • Usage: V8 is also used as the runtime engine for Node.js.
  • SpiderMonkey (Mozilla Firefox):

    • Browsers: Mozilla Firefox.
    • Usage: SpiderMonkey is the JavaScript engine developed by Mozilla.
  • JavaScriptCore (WebKit, Safari):

    • Browsers: Apple Safari, some versions of Google Chrome (before the switch to V8).
    • Usage: JavaScriptCore is the engine used by the WebKit rendering engine, which powers Safari.
  • Chakra (Microsoft Edge, Internet Explorer):

    • Browsers: Microsoft Edge (legacy versions), Internet Explorer.
    • Note: Microsoft Edge has transitioned to using the Blink rendering engine and V8 JavaScript engine, making Chakra obsolete in newer versions of Edge.
  • Nitro (Safari on iOS):

    • Browsers: Safari on iOS devices.
    • Usage: Nitro is an optimized version of the JavaScriptCore engine tailored for iOS.
  • Rhino (Mozilla Rhino):

    • Usage: Rhino is a JavaScript engine for Java applications. It is not commonly used in web browsers but may be utilized in Java-based environments.
  • JerryScript:

    • Usage: JerryScript is a lightweight JavaScript engine designed for resource-constrained devices and the Internet of Things (IoT).
  • Duktape:

    • Usage: Duktape is an embeddable JavaScript engine that can be integrated into various applications and platforms.

It's worth noting that some browsers, especially those based on the Blink rendering engine (like Chrome and new versions of Microsoft Edge), use the V8 JavaScript engine. Additionally, the choice of JavaScript engine can impact the performance of web applications, so browser developers often focus on optimizing and improving their respective engines.

Published On: 2024-01-17