Javascript Notes Revision……..!
WHAT IS JAVASCRIPT?
ANS:JavaScript is a lightweight, cross-platform, single-threaded, and interpreted compiled programming language. It is also known as the scripting language for web pages.
JavaScript is a weakly typed language (dynamically typed). JavaScript can be used for Client-side developments as well as Server-side developments…
How to Link a JavaScript File in HTML ?
Internal JS: We can add JavaScript directly to our HTML file by writing the code inside the <script> tag. The <script> tag can either be placed inside the <head> or the <body> tag according to the requirement.
External JS: We can write JavaScript code in other files having an extension.js and then link this file inside the <head> tag of the HTML file in which we want to add this code.
Features of JavaScript
JavaScript was created in the first place for DOM manipulation. Earlier websites were mostly static, after JS was created dynamic Web sites were made.
Functions in JS are objects. They may have properties and methods just like other objects. They can be passed as arguments in other functions.
Can handle date and time.
Performs Form Validation although the forms are created using HTML.
No compiler is needed.
Applications of JavaScript
Web Development
Web Applications
Server Applications:
Games:
Smartwatches
Machine Learning:
Mobile Applications
Limitations of JavaScript
Security risks:
Performance:
Complexity:
Weak error handling and type checking facilities
Why is JavaScript known as a lightweight programming language ?
JavaScript is considered lightweight due to the fact that it has low CPU usage, is easy to implement,Everything is treated here as an object.A lightweight language does not consume much of your CPU’s resources.
Is JavaScript Compiled or Interpreted or both ?
JavaScript is both compiled and interpreted. In the earlier versions of JavaScript, it used only the interpreter that executed code line by line and showed the result immediately. But with time the performance became an issue as interpretation is quite slow.
The V8 engine initially uses an interpreter to interpret the code. On further executions, the V8 engine finds patterns such as frequently executed functions, and frequently used variables, and compiles them to improve performance.
Is Javascript Synchronous or Asynchronous?
- Well, Javascript is Synchronous, It is a synchronous, single-threaded language. Because it has a single thread that’s why it can only execute one command at a time and the other commands need to wait for executing before the running command executes. And the term synchronous means one at a time.
But What if I say Javascript has asynchronous behaviour also. Yes, I am not totally wrong because we can manipulate the behaviour of javascript by using asynchronous operations like promises, callbacks etc
It can also make AJAX calls, which means if we make an ajax call then the user can still work or get his other commands done while the request is waiting for a response. That means we can manipulate js behaviour in an asynchronous way.
synchronous means to be in a sequence, i.e. every statement of the code gets executed one by one. So, basically a statement has to wait for the earlier statement to get executed.
<script>
document.write("Hi"); // First
document.write("<br>");
document.write("Mayukh") ;// Second
document.write("<br>");
document.write("How are you"); // Third
</script>
IN THIS ABOVE EXAMPLE -> Every line of code waits for its previous one to get executed first and then it gets executed.
NOTE: the synchronous code will block further execution of the remaining code until it finishes the current one.
Asynchronous JavaScript: Asynchronous code allows the program to be executed immediately.
<script>
document.write("Hi");
document.write("<br>");
setTimeout(() => {
document.write("Let us see what happens");
}, 2000);
document.write("<br>");
document.write("End");
document.write("<br>");
</script>
ES5 | ES5 | 2009 | Added: |
2015 | Added: |
In JavaScript, variables can be used to store reusable values. The values of the variables are allocated using the assignment operator(“=”).
There are some basic rules to declare a variable in JavaScript:
These are case-sensitive
Can only begin with a letter, underscore(“_”) or “$” symbol
It can contain letters, numbers, underscore, or “$” symbol
A variable name cannot be a reserved keyword.
JavaScript is a dynamically typed language so the type of variables is decided at runtime.
ES6 the keywords let and const were introduced.
Var is global scope we can access any where in the program.It can be redeclared and re-assign.
Let and const are blocked scope.
HOW THE JAVASCRIPT CODE RUN ?[BEHIND THE scenes]
// 1. When JavaScript code is executed, Execution Context is created and it is called Global Execution Context.
// 2. JavaScript program is executed in TWO PHASES inside Execution Context
// a. MEMORY ALLOCATION PHASE - JavaScript program goes throughout the program and allocates memory of Variables and Functions declared in program.
// b. CODE EXECUTION PHASE - JavaScript program now goes throughout the code line by line and executes the code.
// 3. A Function is invoked when it is called and it acts as another MINI PROGRAM and creates its own Execution Context.
// 4. Return keyword returns the Control back to the PREVIOUS Execution-Context where the Function is called and the Execution Context of the Function is DELETED.
// 5. CALL STACK maintains the ORDER of execution of Execution Contexts. It CREATES Execution Context whenever a Program starts or a Function is invoked and it pops out the Execution Context when a Function or Program ENDS.
// Call Stack Known As…..!
// 0. Call Stack// 1. Execution Context Stack// 2. Program Stack
// 3. Control Stack // 4. Runtime Stack// 5. Machine Stack
//undefined-->>it is like a placeholder
// undefined is a special value in JavaScript that represents the absence of a value.
// It is one of JavaScript's primitive data types.
//Undefined means a variable has been declared but has not yet been assigned a value.
Javascript is synchronous"
// "Javascript is synchronous and single-threaded"
// "Synchronous means line by line execution"
// synchronous single-threaded -javascript can execute one command at a time in a line by line and in specific order.
// having two components
// 1.memory(variable environment)-contains variables and function as key:value pair
// 2.code(thread of execution)->is a place where whole javascript code is executed..
// so what happens when you run javascript program--->
//then the execution context is created.
//when ever the javascript program is executed then the global execution context is created
//memory component-->it is responsible for storing the data
//code component-->it is responsible for executing the code line by line..
// Hoisting in js...!
// "Hoisting is a mechanism in javascript where
// variables and function declarations are moved to
// the top of their scope before the code execution"
Lexical environment tells that your function can what access or what not access.
A closure is a feature of JavaScript that allows inner functions to access the outer scope of a function.
In other words, a closure gives you access to an outer function's scope from an inner function. In JavaScript, closures are created every time a function is created, at function creation time.
if (Math.random() > 0.5) {
var x = 1;
} else {
var x = 2;
}
console.log(x); //OUTPUT:2
if (Math.random() > 0.5) {
const x = 1;
} else {
const x = 2;
}
console.log(x); // ReferenceError: x is not defined
In ES6, JavaScript introduced the let and const declarations, which, among other things like temporal dead zones, allow you to create block-scoped variables.
function makeAdder(x) {
return function (y) {
return x + y;
};
}
const add5 = makeAdder(5);
const add10 = makeAdder(10);
console.log(add5(2)); // 7
console.log(add10(2)); // 12
In this example, we have defined a function makeAdder(x), that takes a single argument x, and returns a new function. The function it returns takes a single argument y, and returns the sum of x and y.
In essence, makeAdder is a function factory. It creates functions that can add a specific value to their argument. In the above example, the function factory creates two new functions—one that adds five to its argument, and one that adds 10.
add5 and add10 both form closures. They share the same function body definition, but store different lexical environments. In add5's lexical environment, x is 5, while in the lexical environment for add10, x is 10.
1. Let, const, var
2. Hoisting
3. Object destructuring
4. Closers
5. Async await
6. Promise
7. Settimeout
8. Fetch
9. map, filter, reduce
10. Object,class, array
11. Arrow function, callback function, normal function
Object destructuring is a useful JavaScript feature to extract properties from objects and bind them to variables.
Destructuring makes it easy to extract only what is needed.
- When destructuring arrays, the order that variables are declared is important.
- Object destructuring is a JavaScript expression that allows us to extract data from arrays, objects, and maps and set them into new, distinct variables. It allows us to extract multiple properties or items from an array at a time.
- that makes it possible to unpack values from arrays, or properties from objects, into distinct variables.
let a, b, rest;
[a, b] = [10, 20];
console.log(a);
// Expected output: 10
console.log(b);
// Expected output: 20
[a, b, ...rest] = [10, 20, 30, 40, 50];
console.log(rest);
// Expected output: Array [30, 40, 50]
JavaScript async / await keywords
Promise() ->pending,fullfield,rejected
promise->resolve->then()
promise->rejected->catch()
Promise takes two argument→>and we define function
And takes two arguments, resolved or rejected.
When we want to call them we can call them by using the callback function.
Inbuilt callback fun(then and catch)....!
// promise is an object that may produce a single value some time in the future
// either a resolved value or a reason that it's not resolved
// a promise may be in one of 3 possible states: fulfilled, rejected, or pending
let complete = true;
// this will become false if we get any errors from our API call.
let promise = new Promise((resolve, reject) => {
if (complete) {
resolve("Success");
} else {
reject("Failure");
}
}
);
//promise.then(successCallback).catch(failureCallback);
promise.then(
(success) => {
console.log(success);
}
).catch(
(failure) => {
console.log(failure);
}
);
setTimeout()
The setTimeout() method executes a block of code after the specified time. The method executes the code only once. The commonly used syntax of JavaScript setTimeout is: setTimeout(function, milliseconds);
function prom(a,b){
return new Promise((resolve,reject)=>{
console.log("Fetching data ,please wait");
var c = a/b;
setTimeout(()=>{
if(a,b){
resolve(`your answer :${c}`);
}else{
reject("Failed to calculate");
}
},2000);
});
}
prom(10,5).then((result)=>{
console.log(result);
}
).catch((error)=>{
console.log(error);
}
);
The prom() function takes two numbers as arguments and returns a promise. The promise will be fulfilled with the result of the division, or rejected with an error if the division is not possible.
In short, this code uses promises to asynchronously fetch data, divide two numbers, and handle errors.
************************************************************************************************************
Here we have to deal with the promise and using the $get() function using jquery cdn and calling the fake api to test that either our promise is fulfilled or rejected..
$get—> It is used to fetch the data from the server and it takes two parameter ajax url and function (data) we want to display .
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
The jQuery library from a CDN, which can improve the performance of our website and make it easier to interact with the DOM.
some of the benefits of using a CDN
Improved performance ,,,Reduced bandwidth usage,,,Increased reliability
A CDN is a network of servers that are distributed around the world. When you load a file from a CDN, the server that is closest to you will be used to serve the file. This can improve the performance of your website, since the file will not have to travel as far to reach you.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- cdn jquery -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<title>Document</title>
</head>
<body>
<script>
function prom() {
return new Promise((resolve, reject) => {
console.log("Fetching data ,please wait");
setTimeout(() => {
$.get(
"https://jsonplaceholder.typicode.com/posts",
function (data) {
resolve(data);
}
).fail((err) => {
reject("fail to load json.");
});
}, 2000);
});
}
prom()
.then((result) => {
console.log(result);
})
.catch((error) => {
console.log(error);
});
</script>
</body>
</html>
**************************************************************************
async fUNCTION ALWAYS RETURN A PROMISE.
WHY this is introduced → it is used to remove the complication like in the promise we are using again and again callback function so this async/await was introduced.
It is easy to use and easy to make the function by using only async keyword.
If we use async before any normal function it becomes a promise function.
//Normal Function
<script>
function test (){
return "Hello Gulab";
}
console.log(test());
</script>
//Promise function
<script>
async function test (){
return "Hello Gulab";
}
console.log(test());
</script>
***********************************************************************
<script>
async function test (){
return "Hello Gulab";
}
//direct calling then function ..
test().then((data)=>{
console.log(data);
});
</script>
<script>
let test = async function (){
return "Hello Gulab";
}
test().then((data)=>{
console.log(data);
});
</script>
<script>
let test = async () => "hello gulab";
test().then((data)=>{
console.log(data);
});
</script>
****************************************************************
Await function
// await function
//we use it inside async function
//await function wait for the promise to resolve
//await function makes the code wait until the promise returns a result
//It is very useful when we are fetching the data from the server using fetch().. either in json format or text format
// async function test(){
// console.log("2 : Message");
// console.log("3 : Message");
// console.log("4 : Message");
// }
// console.log("1 : Message");
// test();
// console.log("5 : Message");
async function test() {
console.log("2 : Message");
await console.log("3 : Message");
console.log("4 : Message");
}
console.log("1 : Message");
test();
console.log("5 : Message");
1 : Message
2 : Message
3 : Message
5 : Message
4 : Message
Async example fetching from third party jsonplaceholder.
<script>
//1ST METHOD
async function test() {
console.log("2 : Message");
const response = await fetch("jsonplaceholder.typicode.com/albums");
console.log("3: Message");
const students = await response.json();
return students;
}
console.log("1 : Message");
let a = test();
console.log("4: Message");
console.log(a);
</script>
*******************************************************
//2ND METHOD
<script>
async function test (){
return(await fetch("jsonplaceholder.typicode.com/albums")).json()).json());
}
test().then((res)=>{
console.log(res);
}).catch((error)=>{
console.log(error);
});
</script>
*******************************************
WE USE TRY AND CATCH FOR ERROR HANDLING WE PUT all the code inside the try and if there is any error that it will go into the catch and that will throw an error.
Example::
<script>
try {
fetch("jsonplaceholder.typicode.com/albums")
.then((res) => {
return res.json();
})
.then((data) => {
console.log(data);
})
.catch((error) => {
console.log(error);
});
} catch (error) {
console.log(error);
}
</script>
****************************************************************************************
MAP,FILTER,REDUCE.
// map method:
//explanation
//The map() method creates a new array with the results of calling a function for every array element.
//The map() method calls the provided function once for each element in an array, in order.
//Note: map() does not execute the function for array elements without values.
const numberss = [1, 2, 3, 4, 5];
const doubled = numberss.map((item) => item * 2);
console.log(doubled);
// filter method:
//explanation
//The filter() method creates an array filled with all array elements that pass a test (provided as a function).
//Note: filter() does not execute the function for array elements without values.
//Note: filter() does not change the original array.
const numbers = [1, 2, 3, 4, 5];
const evens = numbers.filter((item) => item % 2 === 0);
console.log(evens);
// reduce method:
//explanation
//The reduce() method reduces the array to a single value.
//The reduce() method executes a provided function for each value of the array (from left-to-right).
//The return value of the function is stored in an accumulator (result/total).
//Note: reduce() does not execute the function for array elements without values.
const numbersss = [1, 2, 3, 4, 5];
const sum = numbersss.reduce((result, item) => result + item, 0);
console.log(sum);
ARROW FUNCTION..
Arrow function {()=>} is a concise way of writing Javascript functions in a shorter way. Arrow functions were introduced in the ES6 version. They make our code more structured and readable.They are also called Lambda Functions.Arrow functions are anonymous functions i.e. functions without a name and are not bound by an identifier. Arrow functions do not return any value and can be declared without the function keyword.
Arrow Function without Parameters
const gulab = () => {
console.log( "Hi from GeekforGeeks!" );
}
gulab();
**********************************************
Arrow Function with Parameters
const add= ( x, y, z ) => {
console.log( x + y + z )
}
add( 10, 20, 30 );
****************************************
Arrow Function with Default Parameters
const default = ( x, y, z = 30 ) => {
console.log( x + " " + y + " " + z);
}
default( 10, 20 );
<script>
//old way to declare arrow function
// let welcome = function (name) {
// return Hello & welcome ${name}
;
// };
// console.log(welcome("gulab chand"));
// let welcome = (name,age,address) => {
// return Hello & welcome ${name} - ${age} - ${address}
;
// };
// console.log(welcome("gulab chand" ,22,"siwan Bihar"));
// let welcome = (name,age,address) => Hello & welcome ${name} - ${age} - ${address}
;
// console.log(welcome("gulab chand" ,22,"siwan Bihar"));
// console.log(typeof welcome)
// let welcome = name => welcome ${name}
;
// console.log(welcome("gulab chand"));
// console.log(typeof welcome)
// an arrow function is also called the anomyoos function
(() => {
console.log("GULABCHAND KUMAR Gupta");
})();
</script>
Advantages of Arrow Functions
Arrow functions reduce the size of the code.
The return statement and function brackets are optional for single-line functions.
It increases the readability of the code.
Arrow functions provide a lexical binding. It means, they inherit the value of “this” from the enclosing scope. This feature can be advantageous when dealing with event listeners or callback functions where the value of “this” can be uncertain.
Limitations of Arrow Functions
Arrow functions do not have the prototype property.
Arrow functions cannot be used with the new keyword.
Arrow functions cannot be used as constructors.
These functions are anonymous and it is hard to debug the code.
Arrow functions cannot be used as generator functions that use the yield keyword to return multiple values over time.
CALLBACK FUNCTION:WE TAKE A FUNCTION AND PASSED TO ANOTHER FUNCTION.WHEN you do so this function which you passed to another function is a call back function .
It is very powerful in javascript. It gives access to the whole asynchronous world into asynchronous single-threaded language.
Javascript is a synchronous and single-threaded language->It can only do one task at a time in a specific order.
But due to call back we can do async things in javascript.
But if we do all in one function it looks very untighty and unstructured
And not clear code.
// callback hell
// pizza->dough->cheese
// The phenomenon which happens when we nest
// multiple callbacks within a function is called a callback hell.
//call back is a function passed as an argument to another function…..
function getCheese(callback) {
setTimeout(() => {
const cheese = "🧀";
console.log("here is cheese", cheese);
callback(cheese);
}, 2000);
}
function makeDough(cheese, callback) {
setTimeout(() => {
const dough = cheese + "🍞";
console.log("here is dough", dough);
callback(dough);
}, 2000);
}
function bakePizza(dough, callback) {
setTimeout(() => {
const Pizza = dough + "🍞";
console.log("here is the Pizza", Pizza);
callback(Pizza);
}, 2000);
}
getCheese((cheese) => {
makeDough(cheese, (dough) => {
// console.log("made the dough",dough);
bakePizza(dough, (pizza) => {
console.log("got the Pizza finally", pizza);
});
});
});
//The code uses asynchronous functions and callbacks to simulate a process of making pizza by getting cheese, making dough, and baking the pizza.
// Hoisting in js...!
// "Hoisting is a mechanism in javascript where
// variables and function declarations are moved to
// the top of their scope before the code execution"
var x=7;
function getName(){
console.log("Hello Javascript");
}
getName();
console.log(x);
console.log(getName);
********************************************************************************
Debouncing:
Debouncing and throttling are two techniques in JavaScript to optimize the performance of a website or application when dealing with events that can be called frequently, such as scrolling or resizing the window.
- Debounce is most suitable for control events like typing or button clicks.
<!-- What is debounce?
The concept of debouncing is pretty straightforward.
It delays the function invocation by a defined period of time to avoid unnecessary invocations.
So, the function will only be invoked if no event is triggered within that time.
If the user triggers a new event during that time, the time will be reset.
Let’s consider the previous example again.
The issue with the scenario was unnecessary API calls. So, if we define a debounce function with a delay of one second,
it will hold back the API call until one second passes without any user events. If the user presses a key within that second,
The debounce function will reset the delay and wait for another second to make the API call.
We can easily implement a debounce function using the setTimeout() and clearTimeout() functions.
It should also take a callback function and the delay as input parameters. -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Debounce</title>
</head>
<body>
<label>Search Here Gulab: </label>
<input type="text" id="search-bar" />
<script>
var searchBarDom = document.getElementById("search-bar");
var numberOfKeyPresses = 0;
var numberOfApiCalls = 0;
const getSearchResult = debounce(() => {
numberOfApiCalls += 1;
console.log("Number of API Calls : " + numberOfApiCalls);
}, 1000);
searchBarDom.addEventListener("input", function (e) {
numberOfKeyPresses += 1;
console.log("Search Keyword : " + e.target.value);
console.log("Number of Key Presses : " + numberOfKeyPresses);
getSearchResult();
});
function debounce(callback, delay = 1000) {
var time;
return (...args) => {
clearTimeout(time);
time = setTimeout(() => {
callback(...args);
}, delay);
};
}
</script>
</body>
</html>
<!-- Although the user has typed the word JavaScript, only a single API call has been invoked.
So, debouncing has blocked nine unnecessary API calls..-->
****************************************************************************
Throttling:
- Throttle is another technique to minimise unnecessary function
invocations when using event listeners. However, throttle works
a bit differently from debouncing. Instead of delaying,
it invokes the callback function at
regular intervals as long as the event trigger is active. -->
- Throttle is most
suitable for continuous user events like resizing and scrolling. -->
- these two techniques can significantly improve your application’s
performance since they can avoid many unnecessary API calls -->
Both of these techniques help optimise performance and prevent performance issues such as excessive network requests,
lag. Debouncing and throttling both ensure that functions are executed only when needed, preventing unnecessary calculations and allowing us to save resources.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>throttling</title>
</head>
<body>
<label>Search Here Gulab: </label>
<input type="text" id="search-bar" />
<script>
var searchBarDom = document.getElementById('search-bar');
var numberOfKeyPresses = 0;
var numberOfApiCalls = 0;
const getSearchResult = throttle(() => {
numberOfApiCalls += 1;
console.log('Number of API Calls : ' + numberOfApiCalls);
}, 1000);
searchBarDom.addEventListener('input', function (e) {
numberOfKeyPresses += 1;
console.log('Search Keyword : ' + e.target.value);
console.log('Number of Key Presses : ' + numberOfKeyPresses);
getSearchResult();
});
function throttle(callback, delay = 1000) {
let shouldWait = false;
return (...args) => {
if (shouldWait) return;
callback(...args);
shouldWait = true;
setTimeout(() => {
shouldWait = false;
}, delay);
};
}
</script>
</body>
</html>
<!-- As you can see, only three API calls were made in this example when I typed the word JavaScript.
The first call is the initial call, and the other two were made after 5 and 10 key presses, respectively.
So, the throttle function has reduced seven unnecessary API calls. -->