Js Question
Js Question
1. What is JavaScript?
• Primitive Types:
o String: A sequence of characters.
o Number: Numeric values (both integer and floating-point).
o BigInt: For integers of arbitrary length.
o Boolean: true or false.
o undefined: A variable that has been declared but not assigned a value.
o null: Represents the intentional absence of any object value.
o Symbol: A unique and immutable primitive value.
• Non-Primitive Type:
o Object: A collection of key-value pairs. Arrays, Functions, and Dates are also
types of objects.
• == (Loose Equality): Compares two values for equality after performing type coercion
(converting values to a common type).
• === (Strict Equality): Compares two values for equality without performing type
coercion. It checks if both the value and the type are the same. It's almost always
recommended to use === to avoid unexpected bugs from type coercion.
JavaScript
[Link](1 == '1'); // true (string '1' is coerced to number 1)
[Link](1 === '1'); // false (number is not the same type as string)
Type coercion is the automatic conversion of a value from one data type to another. This
happens when using operators like == or when a value is used in a context that expects a different
type (e.g., 2 + '3' results in the string '23').
JavaScript is a dynamically typed language. This means you don't have to declare the type of a
variable in advance. The type of a variable is determined at runtime and can change throughout
the program's execution.
NaN stands for "Not a Number". It's a special numeric value that represents an invalid or
unrepresentable number, often the result of a mathematical operation that failed (e.g., 0 / 0). A
tricky part of NaN is that it doesn't equal itself (NaN === NaN is false). To check for it, you must
use the global isNaN() function or the more reliable [Link]() method.
JavaScript
[Link]([Link](0 / 0)); // true
[Link](isNaN("hello")); // true (coerces "hello" to NaN)
Hoisting is JavaScript's default behavior of moving all declarations (for variables declared with
var and functions) to the top of their current scope before code execution. Initializations are not
hoisted.
• Variables declared with let and const are also hoisted but are not initialized, creating a
"Temporal Dead Zone" until the declaration is encountered.
JavaScript
[Link](myVar); // undefined (declaration is hoisted, but not
initialization)
var myVar = 5;
• undefined: This is the default value of a variable that has been declared but not yet
assigned a value.
• null: This is an intentional assignment. It's used to represent the absence of a value,
explicitly set by a programmer.
9. What are global variables? What are the problems with them? Global variables are
variables declared outside of any function, making them accessible from anywhere in the code.
Problems:
• Name Collisions: Different scripts might accidentally use the same global variable name,
causing conflicts.
• Security Issues: They can be accessed and modified by any script on the page.
• Poor Code Readability: It's hard to track where a global variable is being modified.
10. What is "Strict Mode"? Strict Mode ('use strict';) is a feature in JavaScript that
enforces stricter parsing and error handling. It helps you write cleaner code by preventing certain
actions (like using undeclared variables) and throwing more exceptions.
• var: Function-scoped. Can be re-declared and updated. Hoisted and initialized with
undefined.
• Falsy Values: There are only eight: false, 0, -0, 0n (BigInt zero), "" (empty string),
null, undefined, and NaN.
• Truthy Values: Everything else.
Scope determines the accessibility (visibility) of variables. JavaScript has three types of scope:
• Global Scope: Variables declared outside any function are in the global scope.
• Function Scope: Variables declared inside a function are only accessible within that
function.
• Block Scope: Variables declared with let and const inside a block ({...}) are only
accessible within that block.
A closure is a function that has access to its outer (enclosing) function's variables, even after the
outer function has finished executing. It "remembers" its lexical scope.
JavaScript
function outerFunction() {
let count = 0; // This variable is 'closed over'
return function innerFunction() {
count++;
[Link](count);
};
}
An IIFE is a JavaScript function that runs as soon as it is defined. It's a design pattern used to
avoid polluting the global scope.
JavaScript
The this keyword refers to the object it belongs to. Its value is determined by how a function is
called (the "call-site").
All three methods are used to set the this value for a function.
• call(thisArg, arg1, arg2, ...): Invokes the function immediately, with arguments
passed individually.
• apply(thisArg, [argsArray]): Invokes the function immediately, with arguments
passed as an array.
• bind(thisArg): Returns a new function with this bound to thisArg. It does not
invoke the function immediately.
18. What are arrow functions? How are they different from regular functions?
Arrow functions (=>) provide a more concise syntax for writing functions. Key Differences:
1. Given the same input, will always return the same output.
2. Has no side effects (it doesn't modify any state outside its own scope).
JavaScript
const person = { name: 'Alice' };
[Link]('name' in person); // true
[Link]([Link]('age')); // false
22. What's the difference between dot notation and bracket notation?
• Dot Notation ([Link]): Simpler and more readable. The property name must be a
valid JavaScript identifier.
• Bracket Notation (obj['prop']): More flexible. The property name is a string, so it can
contain spaces, special characters, or be a variable.
JavaScript
const obj = { 'first name': 'John' };
// [Link]([Link] name); // SyntaxError
[Link](obj['first name']); // 'John'
• map(): Creates a new array by applying a function to every element of the original array.
• filter(): Creates a new array with all elements that pass the test implemented by the
provided function.
• reduce(): Executes a "reducer" function on each element of the array, resulting in a
single output value.
• forEach(): Executes a function for each array element. It does not return a value
(undefined). It's used when you want to cause a side effect for each element.
• map(): Executes a function for each array element and returns a new array containing
the results. It's used for data transformation.
26. How can you empty an array? There are several ways, but the two most common are:
A deep copy creates a new object and recursively copies all properties, including nested objects
and arrays.
JavaScript
const nested = [1, [2, 3], [4, [5]]];
[Link]([Link](2)); // [1, 2, 3, 4, 5]
// The argument specifies the depth to flatten.
Asynchronous JavaScript
29. What is asynchronous programming?
Asynchronous programming allows code to run in the background without blocking the main
execution thread. In JavaScript, this is crucial for tasks like making API requests, reading files, or
setting timeouts, ensuring the user interface remains responsive.
Callback Hell (or the "Pyramid of Doom") describes a situation where multiple nested callbacks
make the code hard to read and maintain.
JavaScript
asyncAction1(function(result1) {
asyncAction2(result1, function(result2) {
asyncAction3(result2, function(result3) {
// ...and so on
});
});
});
async/await is syntactic sugar built on top of Promises, making asynchronous code look and
behave more like synchronous code.
JavaScript
async function fetchData() {
try {
const response = await fetch('[Link]
const data = await [Link]();
[Link](data);
} catch (error) {
[Link]('Failed to fetch data:', error);
}
}
You use a standard try...catch block, just like with synchronous code.
The event loop is a mechanism that allows JavaScript to perform non-blocking operations. It
continuously checks the Message Queue for tasks and pushes them onto the Call Stack to be
executed once the stack is empty. This model enables concurrency in a single-threaded
environment.
ES6+ Features
36. What is destructuring assignment?
JavaScript
// Object destructuring
const person = { name: 'Alice', age: 30 };
const { name, age } = person;
[Link](name); // 'Alice'
// Array destructuring
const [first, second] = [1, 2, 3];
[Link](first); // 1
37. What are the spread (...) and rest (...) operators?
They use the same ... syntax but have opposite functions.
JavaScript
// Spread
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5]; // [1, 2, 3, 4, 5]
// Rest
function sum(...numbers) {
return [Link]((acc, curr) => acc + curr, 0);
}
sum(1, 2, 3, 4); // 10
Modules allow you to split your code into separate, reusable files. You can use the export
statement to make variables or functions available to other files and the import statement to use
them.
• Set: A collection of unique values. It's useful for storing a list of items where you don't
want duplicates.
• Map: A collection of key-value pairs, similar to an object. However, a Map allows keys
of any data type, maintains insertion order, and is optimized for frequent additions and
removals of key-value pairs.
Optional chaining allows you to safely access deeply nested properties of an object without
having to check if each level of the chain exists. If any part of the chain is null or undefined,
the expression short-circuits and returns undefined.
This logical operator returns its right-hand side operand when its left-hand side operand is null
or undefined, and otherwise returns its left-hand side operand. It's a way to provide a default
value for potentially nullish variables.
JavaScript
const name = null;
const defaultName = 'Guest';
[Link](name ?? defaultName); // 'Guest'
const count = 0;
[Link](count ?? 10); // 0 (unlike || which would return 10)
The Document Object Model (DOM) is a programming interface for web documents. It
represents the page so that programs can change the document structure, style, and content. The
DOM represents the document as a tree of nodes.
• window: The global object that represents the browser window or tab. It contains the
document object, as well as other things like location, history, and global functions
like setTimeout.
• document: Represents the web page itself (the DOM). It's a property of the window object
([Link]).
Event delegation is a technique where you add a single event listener to a parent element to
manage events for all of its children. This is more efficient than adding an event listener to every
child element, especially for dynamically added elements.
• Capturing Phase: The event "travels down" from the root of the document to the target
element.
• Bubbling Phase: The event "bubbles up" from the target element back to the root of the
document. By default, event listeners operate in the bubbling phase.
Prototypal inheritance is a core concept in JavaScript where objects can inherit properties and
methods from other objects. Every JavaScript object has a private property which holds a link to
another object called its prototype. That prototype object has a prototype of its own, and so on,
until an object is reached with null as its prototype. This is called the prototype chain.
• prototype: A property that exists on constructor functions and points to an object. This
object is what will become the prototype of all instances created by that constructor.
• __proto__: A property that exists on object instances and points to the object's
prototype (the prototype object of the constructor that created it). It's the actual link in
the prototype chain.
The class keyword is syntactic sugar over JavaScript's existing prototype-based inheritance. It
provides a cleaner and more familiar syntax for creating objects and dealing with inheritance, but
it doesn't fundamentally change how JavaScript's object model works.
In a child class constructor, super() is used to call the constructor of its parent class. It must be
called before the this keyword can be used in the constructor. It can also be used to call methods
on the parent class.
• Cookies: Small strings of data stored by the browser. Sent with every HTTP request, have
a small capacity (~4KB), and can have an expiration date.
52. What is the Same-Origin Policy? It's a critical security mechanism that restricts how a
document or script loaded from one origin can interact with a resource from another origin. An
origin is defined by the combination of protocol, hostname, and port.
53. What is CORS (Cross-Origin Resource Sharing)? CORS is a mechanism that uses
additional HTTP headers to tell browsers to give a web application running at one origin, access
to selected resources from a different origin. It's a way to safely relax the Same-Origin Policy.
54. What is the Fetch API? The Fetch API provides a modern, Promise-based interface for
fetching resources across the network (e.g., making HTTP requests). It's a more powerful and
flexible replacement for XMLHttpRequest.
It will output false. This is because floating-point numbers in JavaScript (and most
programming languages) are stored in binary format (IEEE 754) and cannot represent some
decimal fractions with perfect precision. 0.1 + 0.2 results in something like
0.30000000000000004.
JavaScript
for (var i = 0; i < 5; i++) {
setTimeout(function() { [Link](i); }, 1000);
}
It will print the number 5 five times. This is because setTimeout is asynchronous. By the time
the callbacks execute, the loop has already finished, and the variable i (which is in the
global/function scope because of var) holds its final value, 5.
How to fix it? Use let for block scope, or use a closure.
JavaScript
// Fix using let
JavaScript
(function(){
var a = b = 3;
})();
Output:
a defined? false
b defined? true
It returns [1, NaN, 3]. Why? map passes three arguments to its callback: (element, index,
array). parseInt accepts two arguments: (string, radix).
60. Write a function sum that can be called like sum(2)(3)(5)() and returns 10.
JavaScript
function sum(a) {
return function(b) {
if (b) {
return sum(a + b);
}
return a;
};
}
[Link](sum(2)(3)(5)()); // 10
The finally block contains code that will execute after the try and catch blocks, regardless of
whether an exception was thrown or caught. It's typically used for cleanup tasks, like closing a
file or disconnecting from a database.
• SyntaxError: This error is thrown when the JavaScript engine encounters code that
violates the syntax rules of the language. It happens during the parsing phase, before the
code is executed. For example, a missing parenthesis [Link]("hello" would
cause a SyntaxError.
• ReferenceError: This error is thrown when you try to access a variable that has not been
declared. It happens during the execution phase. For example, [Link](myVar)
without declaring myVar first.
You can create a custom error by extending the built-in Error class. This allows you to create
more specific and descriptive error types in your application.
JavaScript
class ValidationError extends Error {
constructor(message) {
super(message); // Call the parent constructor
[Link] = "ValidationError";
}
}
The debugger keyword acts as a breakpoint in your code. When the browser's developer tools
are open, the JavaScript execution will pause at the line where debugger is placed, allowing you
to inspect variables and the call stack at that specific point.
You handle errors in Promises by chaining a .catch() block. It will be executed if any
preceding Promise in the chain is rejected. With async/await, you use a standard try...catch
block.
Tree shaking is a process used by modern module bundlers (like Webpack or Rollup) to
eliminate dead code. It analyzes your import and export statements and includes only the code
that is actually used in your final bundle, which helps reduce the file size.
Lazy loading is a performance optimization technique where you defer the loading of non-critical
resources (like images, scripts, or modules) until they are actually needed. For example, loading
an image only when the user scrolls it into the viewport. This improves initial page load time and
saves bandwidth.
• Debouncing: Groups a burst of events into a single one. It ensures a function is not called
again until a certain amount of time has passed without it being called. A common use
case is a search bar that only triggers the API call after the user stops typing for 300ms.
• Throttling: Ensures a function is called at most once in a specified time interval, no
matter how many times the event fires. A common use case is preventing a function tied
to a scroll event from firing hundreds of times per second.
Frequent, direct DOM manipulation is slow because it can trigger browser reflows and repaints.
To optimize it:
Memoization is an optimization technique where you cache the results of expensive function
calls and return the cached result when the same inputs occur again. It's a way to trade memory
for speed.
• Map: Can have keys of any type. It keeps strong references to its keys, meaning that as
long as the Map exists, the key objects cannot be garbage collected.
• WeakMap: Can only have objects as keys. It holds weak references to its keys. This means
if an object used as a key has no other references in the code, it can be garbage collected,
and its entry will be automatically removed from the WeakMap. This is useful for
preventing memory leaks.
A generator function is a special type of function that can be paused and resumed, allowing it to
produce a sequence of values over time. It is defined using the function* syntax and uses the
yield keyword to return a value and pause its execution.
You can make an object iterable by implementing the iterable protocol. This means the object
must have a property with a [Link] key, which is a function that returns an iterator
object. The iterator object must have a next() method.
JavaScript
const myIterable = {
from: 1,
to: 3,
[[Link]]() {
let current = [Link];
const last = [Link];
return {
next() {
if (current <= last) {
return { done: false, value: current++ };
} else {
return { done: true };
}
}
};
}
};
A transpiler is a tool that reads source code written in one programming language and produces
equivalent code in another language. In the JavaScript world, it's used to convert modern
JavaScript (ES6+) into an older, more widely supported version (like ES5).
• npm (Node Package Manager): It is used to install, manage, and publish packages to the
npm registry. You use it to manage the dependencies in your [Link] file.
• npx (Node Package Execute): It is a package runner that comes with npm. It allows you
to execute a command from an npm package without having to install it globally or
locally in your project's dependencies.
Shadow DOM is a web standard that allows for encapsulation in web components. It lets you
keep the markup structure, style, and behavior of a component hidden and separate from other
code on the page so it doesn't clash. This is a key part of the Web Components suite.
77. What is the difference between attributes and properties on a DOM element?
• Attributes: Are defined by the HTML markup. They are the initial values in the HTML
file (e.g., <input id="my-input" value="hello">). You access them with
[Link]().
• Properties: Belong to the DOM object. They are live values that can change. For
example, if a user types into the input box, [Link] (the property) will change, but
[Link]('value') (the attribute) will still be "hello".
78. What does the defer attribute on a <script> tag do? How is it different from async?
Both async and defer allow the HTML parser to continue while the script is being downloaded.
• async: The script will execute as soon as it's downloaded, which can be at any point and
might interrupt HTML parsing. The order of execution for multiple async scripts is not
guaranteed.
• defer: The script will execute only after the HTML document has been fully parsed, but
before the DOMContentLoaded event. defer scripts also execute in the order they appear
in the document. defer is generally safer for scripts that need to interact with the DOM.
The Critical Rendering Path is the sequence of steps the browser goes through to convert HTML,
CSS, and JavaScript into pixels on the screen. The main steps are:
A Service Worker is a script that your browser runs in the background, separate from a web page.
It acts as a network proxy, intercepting network requests. This enables features like offline
capabilities, push notifications, and background data synchronization.
81. What is the output of typeof []? What about typeof null?
82. How can you check if an object is empty? The most robust way is to use [Link]()
and check its length.
JavaScript
const obj = {};
[Link]([Link](obj).length === 0); // true
• [Link](obj): Prevents new properties from being added and marks all existing
properties as non-configurable. However, the values of existing properties can still be
changed.
• [Link](obj): Does everything [Link]() does, but it also makes all
existing properties read-only (immutable). It's the highest level of immutability for an
object.
The output will be true. The first ! (NOT operator) coerces the truthy string "Hello" into
false. The second ! then negates false, resulting in true. It's a quick way to convert any value
to its boolean equivalent.
Function composition is the process of combining two or more functions to produce a new
function. The output of one function becomes the input of the next.
JavaScript
const add5 = x => x + 5;
const multiplyBy2 = x => x * 2;
86. What does [Link] do? [Link] is a meta-property that is available inside
functions. If a function is called with the new keyword (as a constructor), [Link] will be a
reference to the constructor. If it's called as a regular function, [Link] will be undefined.
It's useful for determining if a function was called as a constructor.
87. What is the output of [1, 2, 3] + [4, 5, 6]? Why? The output will be the string
"1,2,34,5,6". When the + operator is used with an array, the array is first converted to a string
by calling its toString() method, which is equivalent to join(','). So, [1, 2, 3] becomes
"1,2,3" and [4, 5, 6] becomes "4,5,6". Then, the two strings are concatenated.
88. What is the Temporal Dead Zone (TDZ)? The Temporal Dead Zone is a term to describe
the state where variables declared with let and const are un-initialized. They are hoisted, but
you cannot access them before the line of declaration. Trying to access a variable in the TDZ
results in a ReferenceError.
• Imperative Programming: Focuses on how to achieve a result. You write explicit, step-
by-step instructions for the computer to follow. A for loop is a classic imperative
approach.
• Declarative Programming: Focuses on what you want to achieve, without specifying
the step-by-step flow. Array methods like .map() and .filter() are declarative—you
describe the desired outcome, not the loop mechanism.
90. What is the output? [Link](1 < 2 < 3); and [Link](3 > 2 > 1);
• [Link](1 < 2 < 3); outputs true. The expression is evaluated left-to-right. 1 <
2 is true. Then, true < 3 coerces true to the number 1, so 1 < 3 is true.
• [Link](3 > 2 > 1); outputs false. 3 > 2 is true. Then, true > 1 coerces
true to 1, so 1 > 1 is false.
91. What is the purpose of the Proxy object in JavaScript? A Proxy object allows you to
create a wrapper around another object (the "target") and intercept fundamental operations, such
as property lookups, assignments, and function invocations. It's a form of metaprogramming that
enables you to add custom behavior to objects, like validation, logging, or formatting.
92. How can you create a truly private variable in a JavaScript class? The standard way is to
use the # prefix for class fields. This makes the field private to the class, and it cannot be
accessed from outside the class instance.
JavaScript
class MyClass {
#privateField = 'secret';
getPrivateField() {
return this.#privateField;
}
}
93. What is "lifting state up"? This is a pattern commonly used in component-based
frameworks like React. When several components need to share and reflect the same changing
data, it's recommended to lift the shared state up to their closest common ancestor. The ancestor
then passes the state down to the children via props, keeping the data flow unidirectional and
predictable.
94. Explain what [Link]() is for and why it's necessary. [Link](value)
returns true if the value is an array and false otherwise. It's necessary because typeof []
returns "object", which doesn't reliably distinguish an array from a plain object. It's the safest
way to check if a variable is an array.
95. What is the difference between a shallow copy and a deep copy?
• Shallow Copy: Creates a new object or array, but for nested objects or arrays, it only
copies the references, not the values. If you change a nested object in the copy, it will
also change in the original. ([Link]() and the spread syntax ... create shallow
copies).
• Deep Copy: Creates a new object or array and recursively copies all nested objects and
arrays, creating new copies of them as well. The copy is completely independent of the
original.
96. What is the bind method primarily used for? The bind() method creates a new function
that, when called, has its this keyword set to a provided value. Its primary use case is to
preserve the this context when passing a method as a callback, especially in event handlers or
asynchronous operations.
97. What is CORS? CORS (Cross-Origin Resource Sharing) is a browser security mechanism
that allows a server to indicate any origins (domain, scheme, or port) other than its own from
which a browser should permit loading resources. It's a way to relax the Same-Origin Policy. If a
web application at [Link] tries to make a fetch request to [Link], the browser will block it unless
the server at [Link] sends back the appropriate CORS headers (like Access-Control-Allow-
Origin: *).
• [Link]: The element that triggered the event (the actual element that was
clicked, for example).
• [Link]: The element that the event listener is attached to. In event
delegation, these can be different. [Link] will always be the parent
element where the listener was added.
99. Can you describe the Singleton design pattern? The Singleton pattern is a design pattern
that ensures a class has only one instance and provides a global point of access to it. In
JavaScript, this can be achieved using a module or a class that manages its own instance.
JavaScript
const Singleton = (function () {
let instance;
return {
getInstance: function () {
if (!instance) {
instance = createInstance();
}
return instance;
}
};
})();