- int
- boolean
- string
- Symbol
- undefined
- null
- Object {}
- Array []
- compares value
- if are of different types, the values get converted to a common type for conversion (Cohersion)
- compares value, but NO cohersion
- compares memory location/origin
1 == 1;
1 === 1;
true === true;
null == null;
null === null;
undefined === undefined;
[] === [] // false
{} === {} // false
NaN === NaN // false
Something that repeats itself
- iterator value(loop variable) is initialised
- exit condition: If condition is true, then it goes to the next iteration. If false, exit the loop immediately
- an updator: Before next iteration the iterator value is udpdated
- for
- forEach
- for of
- for in
- while
- do while (NOT IMPORTANT)
function fn(){
// do something
}
fn()
fn()
Instead of calling a function/piece of code like this we can use loops.
Loops are used to:
- iterate over arrays and Objects
- repeat the code based on an iterator condition
- only for array like data
const name=['Shihab','Shifa','Althaf']
for(let i=0;i<names.length;i++){
console.log(`name@${i} ${name[i]}`)
console.log(`@${i} ${i}`)
}
- used to iterate over arrays
- no need of loop variable and exit condition
- simplified version of for-loop
const name=['Shihab','Shifa','Althaf']
names.forEach(name=>console.log(`Name is ${name}`))
const name=['Shihab','Shifa','Althaf']
for(let value of names){
console.log(value)
}
const name=['Shihab','Shifa','Althaf']
for(let key in names){
console.log(names[key])
}
let person = {
name: "Deepak",
age: 25,
country: "India",
job: "engineer",
state: "KL",
};
for (const key in person) {
console.log(key);
}
let i=0
while(i<3){
console.log('i',i)
i++
}
A collection of key value pair
const person = {
name: "Praveen",
age: 25,
country: "India",
};
for (const key in person) {
console.log(person[key]);
}
_Syntax: *** objectName.key *** _
let deepak = {
name: "Deepak",
age: 25,
country: "India",
};
deepak.age
- we can pass the key as a string variable inside a pair of square brackets after the object name
_Syntax: ** objectName['key']** _
let deepak = {
name: "Deepak",
age: 25,
country: "India",
};
deepak["name"];
Example usage:
response-1
let keys = ["name", "age"];
response-2
let person = {
name: "Deepak",
age: 25,
country: "India",
job: "engineer",
state: "KL",
};
access respons-2 values using keys from response-1
for (let key of keys) {
console.log(key, "||", person[key]);
}
A piece of code that can be invoked n-number of times
- Each function invocation creates a new Scope and Execution Context
- a function w/o a name is called an anonymus function
- a function we pass to another function as a callback(to be invoked later) is called a callback function
- calling a function like
functionName()
is called function invocation
var name = "Praveen";
name.toUpperCase();
name = "Shihab";
name.toUpperCase();
If we take the above piece of code to convert a name to uppercase it is not reusable. Each time we need to uppercase a new name, we need to re-type the entire logic. In programming we always try to avoid repeation(DRY: Dont Repeat Yourself). If we find a piece of code reusable, then we wrap it inside a function.
function toUpper(str) {
return str.toUpperCase();
}
const upperCasedName = toUpper("shihab");
const toUpper = function (str) {
return str.toUpperCase();
};
const upperCasedName = toUpper("shihab");
- arrow function is the simplified form of normal function
const toUpper = (str) => {
return str.toUpperCase();
};
- compared to normal function, there are few advantages for arrow function, they are:
- shorter syntax
- default
this
binding - implicit return
- if we want to return a single line/expression we can do that by removing the
{}
andreturn
keyword
const toUpper = (str) => str.toUpperCase();
- we just name the variable, but we haven't assigned any value to it
- all the declared variables are assigned a default value of
undefined
var name;
console.log("name is", name); // name is undefined
name='Kiya'
console.log('name is',name) // name is Kiya
We can combine both declaration and initialization into a single line as
var name='Kiya'
- rest operator is used to capture the arguments that we pass to a function. It accept them as an Array
- spread operator is used to spread/merge objects and arrays
// rest operator
function print(arg1, arg2, ...args) {
const friends = ["Praveen", "Deepak"];
const friends1 = ["Azad", "Rameez"];
// SPREAD Operator
const newArr = [...args, ...friends, ...friends1];
console.log("arg1", arg1);
console.log("arg2", arg2);
console.log("arguments", args);
}
print("Shihab", "Shifa", "Althaf");
const praveen = { personalInfo, empInfo };
const personalInfo = {
name: "Praveen",
country: "India",
};
const empInfo = {
companyName: "Manappuram",
yoe: 2,
};
const praveen = { ...personalInfo, ...empInfo };
console.log("Praveen", praveen);
function add(x, y = 0) {
const sum = x + y;
console.log("Sum is ", sum);
}
add(1); // 1
- return new array
- map // no.of entries same as input array length
- filter // no.of entries is less than or equal to the input array length
- return boolean
- every
- some
- return a single element/undefined
- find
- return what ever type we want (IMPORTANT)
- reduce
without reduce
let sum = 0;
const input = [1, 2, 3, 4];
for (let value of input) {
// sum = sum + value;
sum += value;
}
console.log("sum", sum);
with reduce
const sum = [1, 2, 3, 4].reduce(function (acc, value) {
// acc=acc+value
return (acc += value);
}, 0);
console.log("Sum", sum);
- used to return from a function
- we can return with or w/o a value
function add(x, y) {
return x + y;
}
const sum = add(1, 2);
console.log(sum);
function add(x, y) {
return x + y;
}
function add10(a) {
return add(10, a);
}
- when a function returns another function, the inner function can still refer the
scope of parent. This is called
closure
function outter(x) {
// closure over variable x
return function inner(y) {
return x + y;
};
}
const sum = outter(10)(3);
console.log("SUM IS", sum);
- setTimeout(callback,time to wait in ms)
- setInterval(callback, repeat interval in ms)
- synchronous code
- asynchronous async code
console.log("First");
setTimeout(() => {
console.log("Second");
}, 0);
console.log("Third");
Output
// First
// Third
// Second
- Promise is an Object
- it has three states
pending
: being executedresolved
: execution was successrejected
: execution failed
- promise help us to perform some action depending on the success and failure of a time taking or asynchronous operator
- if promise is resolved it will invoke the callback passed to
.then()
- on failure it invokes
.catch()
callback
const samplePromise = new Promise(function callback(resolve, reject) {
// success
if (true) {
resolve("completed!");
}
// failure
else {
reject("failed!");
}
});
samplePromise.then(function onSuccess(successMsg) {
console.log("on success:", successMsg);
}).catch(function onError(errorMsg) {
console.log("on reject: ", errorMsg);
});
const axios = require("axios");
axios
.get("https://jsonplaceholder.typicode.com/todos/1")
.then(function onSuccess(json) {
console.log("data", json.data);
})
.catch(function onFailure(error) {
console.log("error", error.response.status);
});
- modern way of handling promises
async
keyword should be added infront of the function to mark it asyncawait
keyword is used to handle the resolved value of promise- wrap the entire operator in a
try-catch
block for better error handling
async function callAPI() {
try {
const resp = await axios.get(
"https://jsonplaceholder.typicode.com/todos/1"
);
console.log("res", resp.data);
} catch (error) {
console.log("error", error.response.status);
}
}
callAPI();
- where I can access a variable
const | var | let | |
---|---|---|---|
re-declare | ⛔ | ✅ | ⛔ |
re-assign | ⛔ | ✅ | ✅ |
scope | block scope | function-scope | block scope |
const name = "Shihab";
console.log("name", name);
name = "Shihab";
console.log("name", name);
function printName2() {
// var name = "Shihab";
// ReferenceError
console.log("name is ", name);
}
printName2();
// function scope
function printName() {
// block scope
if (true) {
let name = "Shihab";
}
console.log("name is", name);
}
printName();
let index = 10;
for (let index = 0; index < 4; index++) {
console.log("INSIDE | index", index);
}
console.log("OUTSIDE | index", index);
function outter() {
// ✅ scope
// ✅ execution context
let index = 10;
if (true) {
// ✅ scope
// ⛔ execution context
console.log("Hello world");
}
function inner() {
// ✅ scope
// ✅ execution context
let index = 1;
console.log("index", index);
}
inner();
console.log("index", index);
}
outter();