JavaScript for Interviews
Satej Bidvai
Posted on December 7, 2022
This is my first post/blog/article of any sort, so any feedback will be appreciated.
These are my notes which I prepared to revise for JavaScript interviews. Some of the topics are advanced but are a must-know for a intermediate JavaScript developer.
💪 Basics
JavaScript is a dynamically typed language
Data type of variables can be changed during runtime
var justAVariable = 10;
justAVariable = "I am a string now";
/* Does not throw any error */
Variables
Scope | Can be updated? | Can be redeclared? | |
---|---|---|---|
var | FUNCTIONAL | YES | YES |
let | BLOCK | YES | NO |
const | BLOCK | NO | NO |
Data Types
-
Primitive Values
Boolean, String, Number, BigInt, Symbol, Null, Undefined
-
Objects
Everything except primitives are of type Object in JS.
== v/s ===
-
==
checks only for value (type coersion may occur) -
===
checks for both value and type (no type coersion)
Spread Operator
- Spreads an array into elements.
-
Spreads an object into key value pairs.
const arr = [1, 2, 3]; const copyArr = [...arr]; // copyArr = [1, 2, 3] const sum = (a, b, c) => a + b + c; sum(...arr); // Equivalent to sum(1, 2, 3) const obj = { x: 10 }; const copyObj = { ...obj }; // copyObj = { x: 10 }
Rest Parameter
- Condense elements into an array.
-
Function can be called using variable no. of arguments.
const condense = (...params) => { return params; } console.log(condense(1, 2, 3, 4)); // prints [1, 2, 3, 4] console.log(condense(1, 2)); // prints [1, 2]
🫡 Array Methods
map() method
arr.map((element, index, array) ⇒ { /* Modify element */ })
/* returns a new array with modified elements */
const numbers = [1, 2, 3, 4];
const double = numbers.map((ele) => ele * 2); // [2, 4, 6, 8]
filter() method
arr.filter((element, index, array) ⇒ { /* Condition */ })
/* returns a new array whose elements satisfy the condition */
const numbers = [1, 2, 3, 4];
const evenNumbers = numbers.filter((ele) => ele % 2 == 0); // [2, 4]
find() method
arr.find((element, index, array) ⇒ { /* Condition */ })
/* returns the first element satisfying the condition */
const numbers = [1, 2, 3, 4];
const greaterThanTwo = numbers.find((ele) => ele > 2); // 3
reduce() method
arr.reduce((prevEle, currEle, currIndex, array) ⇒ { /* Code */ }, initialVal)
/* returns a single value - the accumulated result of calling the callback function on each element */
const numbers = [1, 2, 3, 4];
const sum = numbers.reduce((prev, curr) => prev + curr, 0); // 10
☝️ Hoisting
Function, variable and class declarations are moved to the top of the scope.
Variable Hoisting
-
var
is hoisted and initialized withundefined
.
console.log(a); // prints "undefined" var a = 10;
-
let
andconst
are hoisted, but not initialized.
console.log(b); // ReferenceError: b is not defined let b = 20;
-
No hoisting for variables that are not declared.
console.log(c); // ReferenceError: c is not defined c = 30;
Function Hoisting
Function declarations are hoisted. (! Arrow functions are not hoisted)
helloWorld(); // Works
function helloWorld() {
console.log("Hello World");
}
Class Hoisting
- Class declarations are hoisted, but not initialised.
⚠️ Function and Class expressions are not hoisted.
🤝 Closure
- A function and it’s lexical scope together form a closure.
- Due to closures, we can access the outer scope of our function.
-
If we return a function, it stores the reference to variables and functions in the outer scope even after the outer function is executed.
function outerFunc() { let str = "Hello World"; return () => console.log(str); } const testClosure = outerFunc(); testClosure(); // prints "Hello World" /* The returned function still remembers the value of str" */
-
NOTE: Only a reference to the variables is stored and not the actual value. So, if you mutate the variable before calling the returned function, it will reflect the updated value.
let arr = []; function outerFunc() { arr.push(1); return () => console.log(arr); } const testClosure = outerFunc(); arr.push(2); testClosure(); // prints [2, 1]
😮💨 IIFE (Immediately Invoked Function Expression)
- Do not have a name ⇒ Anonymous function
-
Executed just after it is defined.
/* Syntax */ ( **function(){}** )(); ( **function(){}**() ); ( **() => {}** )(); !**function(){}**(); +**function(){}**(); -**function(){}**();
-
Used for keeping data private and exposing selected functions.
const iife = (() => { let val = 0; return { getVal: () => val, setVal: (n) => { val = n; }, } })(); iife.setVal(10) console.log(iife.getVal());
👩👦 Prototypal Inheritance
-
All objects inherit properties with the help of the prototype object.
eg. Arrays inherit from Array prototype
The prototype object has a prototype of it’s own. This forms a prototype chain with the last object being null.
The prototype object:
__proto__
-
When we try to access something in an object, it first checks the object, then in it’s prototype, then in the prototype’s prototype, etc.
const arr = []; arr.push(1); // We can acces this due to the arr.__proto__.push() method
👌 Event Loop
A writeup will take too much time to explain 😅
Checkout this video:
What the heck is the event loop anyway? | Philip Roberts | JSConf EU
Posted on December 7, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 28, 2024