1. What are the data types in JavaScript?
There are 7 basic data types (primitive types) and 1 reference type:
- Primitive Types:
string
number
boolean
null
undefined
symbol
bigint
- Reference Type:
8.
object
(includes arrays, functions, etc.)2. What is the difference between null
and undefined
?
null
: A special object representing "no value." It is often explicitly assigned to a variable to indicate that it currently does not reference any object.
undefined
: Indicates a variable has not been assigned a value, or is uninitialized. It's the default value of a declared but unassigned variable.
Differences:
- Different types:
typeof null
is"object"
, whiletypeof undefined
is"undefined"
.
- Semantic difference:
null
is used as an intentional placeholder for "no value," whileundefined
means the variable hasn't been initialized.
3. What is the difference between call
, apply
, and bind
?
The this
Keyword
In JavaScript, the value of
this
depends on its execution context (i.e., how it is called). call
, apply
, and bind
are methods that allow you to explicitly set the value of this
when invoking a function.call
Method
- Usage:
function.call(thisArg, arg1, arg2, ...)
- Functionality: Invokes a function, explicitly setting
this
and passing arguments individually.
- Features:
- Invokes the function immediately.
- The first argument is the
this
value, followed by individual arguments.
function greet(greeting, punctuation) { console.log(greeting + ', ' + this.name + punctuation); } const person = { name: 'Alice' }; greet.call(person, 'Hello', '!'); // Output: Hello, Alice!
apply
Method
- Usage:
function.apply(thisArg, [argsArray])
- Functionality: Invokes a function, explicitly setting
this
and passing arguments as an array.
- Features:
- Invokes the function immediately.
- The second argument is an array of arguments for the function.
greet.apply(person, ['Hi', '?']); // Output: Hi, Alice?
bind
Method
- Usage:
function.bind(thisArg, arg1, arg2, ...)
- Functionality: Returns a new function with
this
bound to the specified value, and allows pre-setting some arguments.
- Features:
- Does not invoke the function immediately.
- Returns a new function that can be called later.
const greetAlice = greet.bind(person, 'Hey'); greetAlice('!'); // Output: Hey, Alice!
Method | Immediate Invocation | Argument Format | Return Value | Use Case |
call | Yes | Individually | Function result | Used when calling a function and explicitly setting this . |
apply | Yes | Array | Function result | Used when calling a function with this , passing arguments as an array. |
bind | No | Individually | New function | Used when creating a function with this permanently bound, ideal for callbacks. |
4. Differences between let
, var
, and const
ㅤ | Scope | Hoisting | Mutability |
var | Function-scoped; available globally if declared outside functions. | Hoisted, but only the declaration is hoisted (initialized to undefined ). | Variables can be reassigned and redeclared within the same scope. |
let | Block-scoped, limited to the enclosing block. | Hoisted but not initialized. Throws a ReferenceError if accessed before declaration. | Variables can be reassigned, but cannot be redeclared within the same scope. |
const | Block-scoped, like let . | Hoisted but not initialized, like let . | Must be initialized at declaration, and cannot be reassigned (though object contents can be modified). |
5. Closures
A closure is when a function "remembers" and continues to access variables from its outer environment, even after that environment has ceased execution.
Key concepts:
- Lexical Scope: A function's scope is determined when it is defined, not when it is executed.
- Function Nesting: Inner functions have access to the outer function's variables.
- Variable Lifetime: Normally, variables inside a function are destroyed after the function completes. However, closures allow these variables to persist.
Example of a closure:
function outerFunction() { let outerVariable = 'I am outside!'; function innerFunction() { console.log(outerVariable); } return innerFunction; } const closure = outerFunction(); closure(); // Output: I am outside!
6. Prototype Chain
In JavaScript, objects inherit properties and methods from other objects via prototypes. Every object has a hidden
[[Prototype]]
reference to another object or null
. This is the basis of inheritance in JavaScript.function Person(name) { this.name = name; } Person.prototype.sayHello = function() { console.log('Hello, ' + this.name); }; const john = new Person('John'); john.sayHello(); // Output: Hello, John
If a property is not found on the object, JavaScript will look up the prototype chain to find it.
7. Event Loop
The event loop is the mechanism in JavaScript that handles asynchronous operations by allowing code execution to be split between synchronous and asynchronous tasks.
- Call Stack: Executes synchronous code.
- Task Queue: Holds asynchronous tasks to be executed after the stack is empty.
- Microtasks: Higher priority tasks like
Promise
callbacks.
- Macrotasks: Lower priority tasks like
setTimeout
.
8. JavaScript Performance Optimization
- Reduce HTTP Requests: Combine files (CSS, JavaScript) to lower the number of HTTP requests.
- Use Content Delivery Networks (CDNs): Serve static assets from multiple server nodes to reduce load times.
- Compress and Minify: Use Gzip, Brotli for compression, and minify code to remove unnecessary characters.
- Image Optimization: Use modern formats like WebP for smaller file sizes.