JavaScript Interview QA
JavaScript Interview QA
JavaScript has seven primitive data types: string, number, boolean, undefined, null,
symbol, and bigint. Non-primitive data types include objects like arrays, functions, and
objects themselves.
let str = "Hello"; defines a string variable holding text. Strings store characters
or words and are enclosed in quotes.
let num = 42; defines a number variable. JavaScript uses the same data type for
integers and floats.
let bool = true; defines a boolean variable, which can only be true or false.
let undef; declares a variable without assigning a value, so it’s undefined.
let n = null; assigns the value null to represent “no value” or an intentionally
empty value.
let symbol = Symbol(); creates a unique Symbol, a primitive used as a unique
identifier.
let bigInt = 123n; defines a bigint for very large integers, denoted by an n
suffix.
let obj = { name: "Alice" }; defines an object, a non-primitive data structure
that holds key-value pairs, here with a property name set to "Alice".
let a;
console.log(a); // undefined
let b = null;
console.log(b); // null
var has function or global scope and is hoisted, meaning it can be used before declaration
(though its value will be undefined). let and const have block scope (limited to the block in
which they are defined), and const cannot be reassigned.
if (true) {
var x = 10; // function-scoped
let y = 20; // block-scoped
const z = 30; // block-scoped and cannot be reassigned
}
console.log(x); // 10 (var is function-scoped, accessible here)
// console.log(y); // Error: y is not defined (block-scoped)
// console.log(z); // Error: z is not defined (block-scoped)
4. Hoisting:
Variables declared with var and function declarations are hoisted to the top of their scope,
meaning they can be used before they are declared. let and const are hoisted but not
initialized until their line of code is reached or you can say for the time being it is temporal
deadzone.
Scope refers to the accessibility of variables and functions in different parts of your code.
There are mainly two types of scope in JavaScript:
Global Scope: Variables defined outside of any function or block can be accessed
from anywhere in the code.
Local Scope: Variables defined within a function or block are only accessible within
that function or block.
Scope Chain: This is the hierarchy of scopes that the JavaScript engine uses to
resolve variable names. When a variable is not found in the local scope, the engine
looks up the chain to the outer scope until it reaches the global scope or finds the
variable.
let globalVar = "I am global";
function outerFunction() {
let outerVar = "I am outer";
function innerFunction() {
let innerVar = "I am inner";
console.log(innerVar); // I am inner
console.log(outerVar); // I am outer
console.log(globalVar); // I am global
}
innerFunction();
outerFunction();
console.log(globalVar); // I am global
In this code, globalVar is declared in the global scope, making it accessible from
anywhere in the code.
outerVar is defined inside outerFunction, making it accessible within
outerFunction and any inner functions (like innerFunction), but not outside of
outerFunction.
innerVar is defined inside innerFunction, so it is only accessible within that
function.
When innerFunction is called, it logs innerVar, outerVar, and globalVar
successfully. However, trying to access innerVar or outerVar outside their respective
functions will result in a ReferenceError, demonstrating the concept of scope and the
scope chain.
This structure illustrates how JavaScript determines variable accessibility through scope and the chain of
scopes it traverses to resolve variables.
6. Shallow Copy and Deep Copy
A shallow copy duplicates an object’s top-level properties, but nested objects or arrays are still
references to the original. A deep copy creates independent copies of nested objects or arrays.
shallowCopy.address.city = "Nowhere";
console.log(original.address.city); // "Nowhere" (affected by shallow
copy)
console.log(deepCopy.address.city); // "Wonderland" (deep copy
unaffected)
9. Event Loop:
JavaScript has a single-threaded event loop, allowing asynchronous operations like
setTimeout, Promises, and event listeners to be handled efficiently. The event loop checks the
call stack and callback queue to determine what to execute next.
console.log("Start");
setTimeout(() => {
console.log("Timeout");
}, 0);
console.log("End");
10. Promise.all:
Promise.all takes an array of Promises and returns a new Promise that resolves when all
input Promises have resolved or rejects if any of the Promises reject.
let p1 = Promise.resolve(1);
let p2 = Promise.resolve(2);
let p3 = Promise.resolve(3);
const obj = {
name: "Alice",
greet: function() {
console.log(`Hello, my name is ${this.name}`);
}
};
here, this.name refers to the name property of the obj object. However, when
greetFunc is called without the object context, this becomes undefined in non-strict
mode.
In the example, NaN results from invalid mathematical operations, and it's unique in that
it does not equal itself.
"use strict";
function example() {
x = 3.14; // ReferenceError: x is not defined
}
example();
In strict mode, variables must be declared with var, let, or const. The code
above throws an error because x is not declared.
function greet(name) {
return `Hello, ${name}`;
}
setTimeout(function() {
console.log("This is an anonymous function!");
}, 1000);
console.log(factorial(5)); // 120
In this example, fact is the name of the function expression, allowing it to be called
recursively.
function declaredFunc() {
return "I'm a declaration!";
}
In this example, declaredFunc can be called before its definition due to hoisting, while
exprFunc cannot be called before its definition.
if (true) {
let innerVar = "I am inside!";
console.log(innerVar); // I am inside!
console.log(outerVar); // I am outside!
}
function shadowingExample() {
let x = "outer";
function inner() {
let x = "inner"; // shadows outer x
console.log(x); // inner
}
inner();
console.log(x); // outer
}
shadowingExample();
In this example, a and b are parameters, and 5 and 3 are the corresponding arguments.
// Pure function
function square(x) {
return x * x; // always returns the same output for the same input
}
console.log(square(4)); // 16
// Impure function
let counter = 0;
function incrementCounter() {
counter++; // modifies external state
return counter;
}
console.log(incrementCounter()); // 1
console.log(incrementCounter()); // 2