Last active
          July 24, 2020 02:30 
        
      - 
      
 - 
        
Save m90khan/6a07c23e215205eeff6deab0704e9cdd to your computer and use it in GitHub Desktop.  
Revisions
- 
        
m90khan revised this gist
Jul 24, 2020 . 2 changed files with 198 additions and 144 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,34 +1,49 @@ // Topic: Arrays /* Topics Covered: - Let, Const -> Fixed Arrays - Reference to Origin - CallBack & Higher Order Functions - MAP | Find | Filter - Some and Every - Ternary Operator - Arrow Function - Array Sort (sort numbers , strings) - Spread */ //* Primitive Datatypes vs Reference Datatypes // const bank = 250; // bank = 100; // console.log(bank); //Uncaught TypeError: Assignment to constant variable. /* - Changes can be made in arrays when using const which we could not do when using const - in primitive ddta types - if we change the entire array then it will throw error . modification can be made but - not entire array */ // const names = ["Bill"]; // const newArray = ["khan"]; // names[0] = "KhanX"; // names.push(newArray[0]); // names = []; // Uncaught TypeError: Assignment to constant variable. // console.log(names); /* * When using LET - In primitive data types, we can change the value of the variable - In reference data types ARRAYS AND OBEJCTS, even if we change the value in the new assigned variable, - the original array will also change - original array. because of reference */ /* Example of usin LET @@ -61,20 +76,26 @@ console.log(newTweet); */ // Topic: CALLBACK & HIGHER ORDER FUNCTIONS /* videos.forEach(function (video) - Function that takes another function as a parameter is called higher order function - Callback function is a function that executes based on event */ /* - ForEach simply loops over the array but does not actually return us anything const videos = ["hi", "jennifer", "watch TV"]; videos.push("marvin"); console.log(videos); * example of higher order callback function videos.forEach(function (video) { console.log(video.length); console.log(video.slice(1, video.length)); @@ -100,11 +121,17 @@ repeater(function () { }); */ // Topic: MAP, Find,Filter /* - MAP : Create a copy of the array , loop over it and can run a function for modification - MAP always return us a value array.map(function(currentValue, index, arr), thisValue) * function(currentValue, index, arr): It is required parameter and it runs on each element of array. It contains three parameters which are listed below: * currentValue: It is required parameter and it holds the value of current element. * index: It is optional parameter and it holds the index of current element. * arr: It is optional parameter and it holds the array. * thisValue: It is optional parameter and used to hold the value of passed to the function. */ /* @@ -114,19 +141,19 @@ const videos = [ "country is just a love land", "could js take over every application", ]; const mapvideos = videos.map((video, index) => { console.log(video, index); return video.toUpperCase(); }); console.log(`Original Array: ${videos}`); //Original Array : Stays same ["I love apples","country is just a land","could js take over every application" ]; console.log(`Map Array : ${mapvideos}`); // ["I LOVE APPLES", "COUNTRY IS JUST A LAND", "COULD JS TAKE OVER EVERY APPLICATION"] */ // - Find /* - Find : loop over an array and returns only the value/string that we are looking for. - Only the first matched value */ /* @@ -136,9 +163,9 @@ const findvideos = videos.find(function (video) { console.log(`Find Array : ${findvideos}`); // "I love apples", */ //- Filter /* - Filter : loop over an array and returns all the values/strings that we are looking for. */ /* const filtervideos = videos.filter(function (video) { @@ -164,10 +191,11 @@ const filtergames = games.filter(function (game) { console.log(filtergames); */ // Topic: Some and Every /* - Only return us either a true or false value - Every: it is like && . if all values satisfies the condition return true - Some: If only value satisfies , return true else false */ /* @@ -189,11 +217,12 @@ console.log(everyRating); console.log(someRating); */ // Topic: Ternary Operator /* - More like a If statement - condition ? do this : else this */ /* const videos = [ "I love apples", @@ -214,30 +243,30 @@ const ternaryVid = videos.map(function (video) { console.log(ternaryVid); // ["greater than", "html5", "greater than", "greater than"] */ // Topic:Arrow Function /* - As we use a ton of callback and anonymous function, it is best to use arrow function - Normal way const everyRating = games.every( (game)=> { return game.rating > 5; }); - Shortened way: when only need to return a value , no need for comlex math like assigning new variable - Then there is no need for return as it assuedmed that after => then next line will be returned - const everyRating = games.every( (game)=> game.rating > 5;); */ // Topic: SORT /* - Sort items in an array - SOrtin is somewhat wierd in JS as it sorts string fine but not well when it comes to numbers - because the numbers are first converted to string then compare results in wierd behavior - The best way to solve this is to use a function which returns a-b . - a compare function which returns either negative 0 or positive value. - if result negative then a will be sorted before b . - if the result is positive then b wll be sorted before a - if both values same then nothing changes const rating = [5, 2, 4, 45, 22, 3, 1]; a = 5 b = 2 [2, 5, 4, 45, 22, 3, 1]; @@ -275,13 +304,13 @@ rating.sort((a, b) => { 2: {title: "GTA4", rating: 8} 3: {title: "GTA", rating: 9} */ // Topic: Copies of Arrays /* - previously when we sort arrays it keeps its reference. better to create a copy not to mess - with the original array - 1. Spread creates a copy of the array - 2. spread can also be used to split strings and concatenate multiple strings toggetehr - p.s concat does not change the existing array */ /* This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,38 +1,58 @@ // Topic: Objects /* Topics Covered: - Execution Context (Creation and Execution Phase) - Hoisting - CallStack - This Keyword - Bind, Call and Apply - Object-Oriented Programming - Constructor, Prototype, Prototypal Inheritance - Class (super()) */ //* Global Execution and Hoisting /* - JS is a single threaded language. meaning the code will run line by line - Before code even runs, the JS engine automatically creates global exxecuton context * Creation Phase - In that creation phase, it creates a global object (in browser case, window object) - and a this keyword , also a memory is allocated to declared functions along with scope chain -scope chain where hoisting is performed. the global execution context needs to know the scope of stored declaration what is available where - JS engine takes our function, declaration, variables and stored them on the global objects memory * Execution Phase : When our code starts running - Hoisting : In the creation phase of Global execution context as our function declaration already stored. - so it won't error out because the function is already available in the memory before the execution phase hello(); function hello() { console.log("hello"); } - same is the case for Variable var. */ // var varRuns; // console.log(varRuns); // we get undefined // var varRuns = 50; // variable declaration also gets hoisted but the value does not // but this is not a problem anymore because we are using let and const // hello(); // function hello() { // console.log("hello"); // } //Topic: CallStack /* - Javascript keping track on how our code runs : stack - When a function is invoked, it gets its own execution context, it will runs until - its complete and the Execution context will be removed - return in to global execution context window */ /* @@ -55,12 +75,12 @@ hello(); console.log("code is finished Running"); */ //Topic: This Keyword /* - Keyword that gets created in the execution context or on invoking another function - It is basically a pointer refers to an object - it can change based on the object it points to . - work best when it points to an object - can also be used in the DOM in the event listener */ @@ -76,7 +96,7 @@ const user = { user.hello(); // this refers to user object //* Another example const userName = { name: "ukhano", @@ -87,7 +107,7 @@ const admin = { }; function hello() { //* gives the ability to avoid duplication of code console.log(this.name.toUpperCase()); } userName.hi = hello; @@ -97,20 +117,21 @@ userName.hi(); admin.hi(); */ // * This Keyword: function inside a methiod /* * Arrow Function solves the problem of scope of this variable - when we are invoking another function inside a method,, this kyword wont be propagated inside -the function as it will have its own scope and return undefned - Old solution: we create a variable inside function where we had that access to this keyword - so to use that variable in the children let self = this; const getVideos = function () { console.log(`length of videos is ${self.videos.length}`); }; * New solution: arrow function solve this by giving us access to its parent parent. - However using arrow fnction on a method results this keywrd points to window object */ /* @@ -130,17 +151,18 @@ const userInfo = { userInfo.greet(); */ // Topic: Bind Call Apply /* - Function is a special object - All function have access to special method Bind Call Apply - Gives a bit more control over the This keyword * to give access of object to a outside function * Bind : to call a method on a function by passing a reference of the object const nameBind = userRegister.bind(person); - If we need to pass in argments then we first have to bind the object then passing the arguments. function userRegister(a , b) { this.getName(); @@ -150,10 +172,10 @@ function userRegister(a , b) { const nameBind = userRegister.bind(person); nameBind( 1, 4); * Call : we do not store the function reference of the object like we did in Bind instead we invoke it directly * also can pass arguments if needed userRegister.call(person, 1, 7); * Apply is same as call except we pass aruments in an array userRegister.apply(person, [1, 7 ]); */ @@ -166,40 +188,39 @@ const person = { }, }; function userRegister(a, b) { this.getName(); console.log(this); console.log(a + b); } // const nameBind = userRegister.bind(person); // nameBind(1, 4); // bIND const nameBind = userRegister.bind(person); // bind store the reference to this in userRegister nameBind(1, 5); * Call userRegister.call(person, 1, 7); // immediately invoking it. first argument is the object reference and the next two can be normal arguments *Apply userRegister.apply(person, [1, 7]); // same as call but we use an array to pass it arguments */ // Topic: Object Oriented Programming OOP /* - creating something based on the objects - Constructure Function: A function that basically generates an object (capatilze) - Example of Bellboy of a hotel in the sense of factory * new : creates a new empty object and sets the THIS keyword to the new empty object * and based on the properties, we pass it as argumebts for the new created created object */ /* function Todo(name, age, done) { console.log(this); // Empty object {} this.name = name; this.age = age; this.done = done; @@ -209,22 +230,24 @@ function Todo(name, age, done) { } const todo1 = new Todo("khan", 29, true); todo1.getName(); console.log(todo1); */ // Topic: Prototype /* - There is duplication of code becaause we are attaching every method to each newly created instance of the constructor function. - if we have 5 methods and 100 new created objects then those methods needs to be stored somewhere in memory. duplication * Prototype comes to rescue - Every object has a property called prototype . it is simply a reference to a another object - and contain common properties and attributes across all instances - so it best to add all methods in a prototype in the constructer function instead of generating it everytime on newly created object instance - Newly create object inherit the property of the prototype of the constructor function */ /* function Todo(name, age, done) { //console.log(this); @@ -233,22 +256,23 @@ function Todo(name, age, done) { this.done = done; } Todo.prototype.getName = function () { console.log(this.name, this.age); }; const todo1 = new Todo("khan", 29, true); console.log(todo1); todo1.getName(); */ // Topic: Prototypal Inheritance (CAll for properties inherit , Object.create(constructor1.prototype); ) /* - The goal is copy over functions/methods and properties from one constructor Function to another Enemy.call(this, life, name, level); - we run a call method on Enemy to run the constructor function of Enemy but THIS keyword will refer to Dragon - We can create a prototype for the Dragon function and copy (Inherit) the methods from the Enemy Constructor function - To inherit the methods to another constructor function Dragon.prototype = Object.create(Enemy.prototype); - resulting in prototype chain - Constructor function and prototyping is somewhat not so cool because we are somewhat trying to emulate classes */ @@ -267,13 +291,14 @@ Enemy.prototype.attack = function () { console.log(`${this.name} has attacked`); }; //* Dragon constructor function function Dragon(life, name, level, color, spell) { Enemy.call(this, life, name, level); // this will refer to Dragon here this.color = color; this.spell = spell; } // Inhherit Prototype Dragon.prototype = Object.create(Enemy.prototype); Dragon.prototype.fire = function () { console.log("fire"); @@ -287,13 +312,13 @@ newDragon.attack(); //khan has attacked newDragon.fire(); //fire */ // Topic: Class /* - class is a simple and clean mthod rather than using counstructure function and prototype. - instead of using call method , - we use super() and extends the class our constructor class to the one we want to inherit */ class Enemy { constructor(life, name, level) { this.life = life; @@ -311,10 +336,11 @@ const tiger = new Enemy(2, "Simba", 10); console.log(tiger); tiger.attack(); //* What if we need a more specific enemy // * Dragon constructor class class Dragon extends Enemy { constructor(life, name, level, color, spell) { super(life, name, level); // * to get the properties from targeted constructor function instead of using CALL this.color = color; this.spell = spell; } @@ -329,4 +355,3 @@ newDragon.getInfo(); //2 "khan" 10 newDragon.attack(); //khan has attacked newDragon.fire(); //fire  - 
        
m90khan created this gist
Jul 23, 2020 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,37 @@ class Animator { constructor(selector) { this.selector = document.querySelector(selector); } fadeOut(time, toggle) { if (toggle && this.selector.classList.contains("fadeOut")) { this.selector.style.opacity = 1; this.selector.classList.remove("fadeOut"); } else { this.selector.style.transition = `all ${time}s ease`; this.selector.style.opacity = 0; this.selector.classList.add("fadeOut"); } } move(time, toggle, { x = 0, y = 0 }) { if (toggle && this.selector.classList.contains("move")) { this.selector.style.transform = `translate(0, 0)`; this.selector.classList.remove("move"); } else { this.selector.style.transition = `all ${time}s ease`; this.selector.style.transform = `translate(${x}%, ${y}%)`; this.selector.classList.add("move"); } } } const intro = new Animator(".intro"); const btnMove = new Animator(".btn"); // const btn = new Animator(".btn"); const btn = document.querySelector(".btn"); btn.addEventListener("click", () => { intro.fadeOut(0.5, true); intro.move(0.5, true, { x: 50, y: 50 }); btnMove.move(0.5, true, { x: -50, y: -50 }); }); This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,313 @@ // Primitive Datatypes vs Reference Datatypes // const bank = 250; // bank = 100; // console.log(bank); //Uncaught TypeError: Assignment to constant variable. /* Changes can be made in arrays when using const which we could not do when using const in primitive ddta types if we change the entire array then it will throw error . modification can be made but not entire array */ // const names = ["ed"]; // const newArray = ["ed"]; // names[0] = "KhanX"; // names.push(newArray[0]); // // names = []; // Uncaught TypeError: Assignment to constant variable. // console.log(names); /* WHen using LET In primitive data types, we can change the value of the variable In reference data type, even if we change the value in the new assigned variable, the original array will also change original array. because of reference */ /* Example of usin LET let bank = 250; let newbank = 250; console.log(bank, newbank); newbank = 500; console.log(bank, newbank); const names = ["khan", "julie", "kevin"]; const newNames = names; newNames.push("hard"); console.log(newNames); // change array console.log(names); // original array but get modified because of reference const tweet = { name: "khan", tweets: 15, age: 26, }; const newTweet = tweet; newTweet.name = "Khan Baba"; console.log(tweet); console.log(newTweet); */ //CALLBACK & HIGHER ORDER FUNCTIONS /* videos.forEach(function (video) // Function that takes another function as aparameter is called higher order function */ /* const videos = ["hi", "jennifer", "watch TV"]; videos.push("marvin"); console.log(videos); //example of higher order callback function videos.forEach(function (video) { console.log(video.length); console.log(video.slice(1, video.length)); }); // Another Example of higher order function function repeater(fn) { fn(); fn(); } function hello() { console.log("Hello"); } repeater(hello); // anonymous higher order function repeater(function () { console.log(`Helloooo`); }); */ // MAP FIND FILTER /* // MAP : Create a copy of the array , loop over it and can run a function for modification */ /* const videos = [ "I love apples", "HTML5", "country is just a love land", "could js take over every application", ]; const mapvideos = videos.map((video) => { console.log(video); return video.toUpperCase(); }); console.log(videos); //["I love apples","country is just a land","could js take over every application" ]; console.log(`Map Array : ${mapvideos}`); // ["I LOVE APPLES", "COUNTRY IS JUST A LAND", "COULD JS TAKE OVER EVERY APPLICATION"] */ //Find /* // Find : loop over an array and retrns only the value/string that we are looking for. Only the first matched value */ /* const findvideos = videos.find(function (video) { return video.includes("love"); }); console.log(`Find Array : ${findvideos}`); // "I love apples", */ //Filter /* // Filter : loop over an array and retrns all the values/strings that we are looking for. */ /* const filtervideos = videos.filter(function (video) { return video.length < 10; }); console.log(`Filter Array : ${filtervideos}`); //["I love apples", "country is just a love land",] const games = [ { title: "GTA", rating: 9 }, { title: "GTA4", rating: 8 }, { title: "CAll of duty", rating: 5 }, { title: "MOHA", rating: 6 }, ]; const filtergames = games.filter(function (game) { if (game.rating < 7) { return console.log(game.rating); } else { return game.title; } }); console.log(filtergames); */ // Some and Every /* Only return us either a true or false value Every: it is like && . if all values satisfies the condition return true Some: If only value satisfies , return true else false */ /* const games = [ { title: "GTA", rating: 9 }, { title: "GTA4", rating: 8 }, { title: "CAll of duty", rating: 5 }, { title: "MOHA", rating: 6 }, ]; const everyRating = games.every(function (game) { return game.rating > 5; }); const someRating = games.some(function (game) { return game.rating > 8; }); console.log(everyRating); console.log(someRating); */ // Ternary Operator /* More like a If statement condition ? do this : else this */ /* const videos = [ "I love apples", "html5", "country is just a love land", "could js take over every application", ]; const ternaryVid = videos.map(function (video) { return video.length < 10 ? video : "greater than"; // if (video.length < 8) { // return video; // } else { // return "greater than"; // } }); console.log(ternaryVid); // ["greater than", "html5", "greater than", "greater than"] */ //Arrow Function /* As we use a ton of callback and anonymous function, it is best to use arrow function // Nrmal way const everyRating = games.every( (game)=> { return game.rating > 5; }); // Shortened way: when only need to return a value , no need for comlex math like assigning new variable Then there is no need for return as it assuedmed that after => then next line will be returned const everyRating = games.every( (game)=> game.rating > 5;); */ // SORT /* Sort items in an array SOrtin is somewhat wierd in JS as it sorts string fine but not well when it comes to numbers because the numbers are first converted to string then compare results in wierd behavior The best way to solve this is to use a function which returns a-b . a compare function which returns either negative 0 or positive value. if result negative then a will be sorted before b . if the result is positive then b wll be sorted before a if both values same then nothing changes const rating = [5, 2, 4, 45, 22, 3, 1]; a = 5 b = 2 [2, 5, 4, 45, 22, 3, 1]; rating.sort((a, b) => { console.log(a , b); return a - b; // ascending a-b // descending b-a }); */ // const items = ["Apple", "Banana", "citrus", "Mango"]; // const rating = [5, 2, 4, 45, 22, 3, 1]; // items.sort(); // rating.sort((a, b) => { // return a - b; // ascending a-b // descending b-a // }); // console.log(items); // console.log(rating); // const games = [ // { title: "GTA", rating: 9 }, // { title: "GTAVI", rating: 8 }, // { title: "CAll of duty", rating: 5 }, // { title: "MOHA", rating: 6 }, // ]; // games.sort((a, b) => { // return a.rating - b.rating ; // }); // console.log(games); //Result console.log(games); /* (4) [{…}, {…}, {…}, {…}] 0: {title: "CAll of duty", rating: 5} 1: {title: "MOHA", rating: 6} 2: {title: "GTA4", rating: 8} 3: {title: "GTA", rating: 9} */ //Copies of Arrays /* previously when we sort arrays it keeps its reference. better to create a copy not to mess with the original array 1. Spread creates a copy of the array 2. spread can also be used to split strings and concatenate multiple strings toggetehr p.s concat does not change the existing array */ /* const rating = [5, 2, 4, 45, 22, 3, 1]; const spreadRating = [...rating]; // creates a copy of the array spreadRating.sort(); spreadRating.sort((a, b) => { return a - b; // ascending a-b // descending b-a }); console.log(rating); console.log(spreadRating); const name = "TheWebsiteKitchen"; const splitName = name.split(""); console.log(splitName); const singleLetters = [...name]; console.log(singleLetters); const names = ["khan", "Mohsin"]; const namesOther = ["Jon", "Snow"]; const allNames = names.concat(namesOther); console.log(allNames); const spreadALL = [...names, ...namesOther]; console.log(spreadALL); */ This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,117 @@ /* ASYNC: To get data frm the servers in the background live a goolge typing */ /*otherFucnt(); console.log("start"); function otherFucnt() { setTimeout(() => { console.log("async"); }, 2000); } console.log("end"); */ //Callbacl and Callback HEll . onSuccess, onFailure /* console.log("start"); function login(email, password, callback) { setTimeout(() => { callback({ email: email }); }, 5000); } function loginVidoes(email, callback) { setTimeout(() => { callback(["video1", "video2"]); }, 5000); } const user = login("m90khan", "a123312", (user) => { console.log(user.email); loginVidoes(user.email, (videos) => { console.log(videos); }); }); */ // will give undefined because the function did not return anything by // the time we console the user /* Promises when we fetching data from an api , we migt not get the data instead maybe get error Promises simply the callback promise is an object which either give a result or a faailure */ // const promise = new Promise((resolve, reject) => { // setTimeout(() => { // // resolve({ user: "khan" }); // reject(new Error("user not found")); // }, 2000); // }); // function loginVidoes(email, callback) { // setTimeout(() => { // callback(["video1", "video2"]); // }, 5000); // } // promise // .then((user) => { // console.log(user); // }) // .catch((err) => { // console.log(err); // }); // Refatcor into promise function login(email, password) { return new Promise((resolve, reject) => { setTimeout(() => { resolve({ email: email }); }, 5000); }); } function loginVidoes(email) { return new Promise((resolve, reject) => { setTimeout(() => { resolve(["video1", "video2"]); }, 5000); }); } // const user = login("m90khan", "a123312", (user) => { // console.log(user.email); // loginVidoes(user.email, (videos) => { // console.log(videos); // }); // }); login("m90khan", 12345) .then((user) => { loginVidoes(user.email); }) .then((video) => console.log(video)); Promise.all([login, loginVidoes]).then((result) => console.log(result)); //ASYNC AWAIT async function displayUser() { try { const loginuser = await login("khan"); const videos = await loginVidoes(login.email); } catch (err) { console.log(err); } } displayUser(); This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,39 @@ // Deconstruct , IIFE, Closures, Modules /*Deconstruct : to get a specific number of items from an array or an object instead of assigning one by one to a variables */ // const items = ["apple", "banana", "carrot"]; // const [apple, banana, ...rest] = items; // console.log(apple); // // ... is more like spread/rest operator. we can use it for deontructing and spreading // // in the below case, we can add 'more banana' // const newItems = [...items, "more banan"]; // const user = { // name: "kam", // photos: ["khan", "youtube"], // analytics: { // subscribers: 1000, // age: 50, // }, // }; // // const photos = user.photos; // const { photos, age } = user; // /* IIFE : immediately invoked function expression // automatically invoked. better use is libraries // */ // function hello() { // console.log("hello"); // } // hello(); // //iffe // (function hello() { // console.log("hello"); // })(); This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,332 @@ // Objects //Global Execution and Hoisting /* JS is a single threaded language. meaning the code will run line by line - Before code even runs, the JS engine automatically creates global eecuton context Creation Phase - In that creation phase, it creates a global object (in browser case, window object) and a this keyword , also a memory is allocated to declared functions along with scope chain -scope chain where hoisting is performed. the global execution context needs to know the scope of stored declaration what is available where - JS engine takes our function, declaration, variables and stored them on the global objecta memory Execution Phase : When our code starts running /Hoisting : In the creation phase as our function declaration already stored. so it won't error out because the function is already available in the memory before the execution phase */ // console.log(varRuns); // we get undefined // var varRuns = 50; // variable declaration also gets hoisted but the value doesnot // but this is not a problem anymore because we are using let and const // hello(); // function hello() { // console.log("hello"); // } //CallStack /* When a function is invoked, it gets its own execution context, it will runs until its complete and the Execution context will be removed returnin to global exxecution contexxt window */ /* function hello() { console.log(`hello there ${name}`); changeName(); console.log("hello() is finished"); } function changeName() { name = "Khan"; console.log(`we changed name to ${name}`); console.log("changeName is done"); } let name = "khan FIrst"; hello(); console.log("code is finished Running"); */ //This Keyword /* Keyword that gets created in the execution context or on invoking another function It is basically a pointer refers to an object it can change based on the object it points to . work best when it points to an object - can also be used in the DOM in the event listener */ /* console.log(this.window); const user = { name: "khanX", hello: function () { console.log(this.name); }, }; user.hello(); // this refers to user object //Another example const userName = { name: "ukhano", }; const admin = { name: "admin", }; function hello() { // gives the ability to avoid duplication of code console.log(this.name.toUpperCase()); } userName.hi = hello; admin.hi = hello; userName.hi(); admin.hi(); */ // This Keyword: function inside a methiod /* Arrow Function solves the problem of scope of this variable when we are invoking another function inside a method,, this kyword wont be propagated inside the function as it will have its own scope and return undefned Old solution: we create a variable inside function where we had that access to this keyword so to use that variable in the children let self = this; const getVideos = function () { console.log(`length of videos is ${self.videos.length}`); }; New solution: arrow function solve this by giving us access to its parent parent. However using arrow fnction on a method results this keywrd points to window object */ /* const userInfo = { name: "kevin", videos: ["html5", "JS", "React"], greet: function () { console.log(this); console.log(this.name); const getVideos = () => { console.log(`length of videos is ${this.videos.length}`); }; getVideos(); }, }; userInfo.greet(); */ // Bind Call Apply /* Function is a special object All function have access to special method Bind Call Apply Gives a bit more control over the This keyword to give access of object to a outside function // Bind : to call a methd on a function by passing a reference of the object const nameBind = userRegister.bind(person); If we need to pass in argments then we first have to bind the object then passing the arguments. function userRegister(a , b) { this.getName(); console.log(a+b) } const nameBind = userRegister.bind(person); nameBind( 1, 4); //Call : we do not store the function reference of the object like we did in Bind instead we invoke it directly also can pass arguments if needed userRegister.call(person, 1, 7); //Apply is same as call except we pass aruments in an array userRegister.apply(person, [1, 7 ]); */ /* const person = { fName: "Khan", lName: "mohsin", getName() { console.log(this.fName, this.lName); }, }; // function userRegister() { // this.getName(); // } function userRegister(a, b) { this.getName(); console.log(a + b); } // const nameBind = userRegister.bind(person); // nameBind(1, 4); // bIND const nameBind = userRegister.bind(person); nameBind(1, 5); // Call userRegister.call(person, 1, 7); //Apply userRegister.apply(person, [1, 7]); */ // OOP /* creating something based on the objects Constructure Function: A function that basically generates an object (capatilze) Example of Bellboy of a hotel in the sense of factory // new : creates a new empty object and sets the THIS keyword to the new empty object and based on the properties, we pass it argumebts for the new created created object */ /* function Todo(name, age, done) { console.log(this); // Empty object {} this.name = name; this.age = age; this.done = done; this.getName = function () { console.log(this.name); }; } const todo1 = new Todo("khan", 29, true); console.log(todo1); */ // Prototype /* There is duplication of code becaause we are attaching each method to each newly created instace of the constructor function. if we have 5 methods and 100 new created objects then those methods needs to be stored somewhere in memory. duplication Prototype comes to rescue Every object has a property called prototype . it is simply a reference to a another object and contain common properties and attributes across all instances so it best to add all methods in a prototype in the constructer function instead of generating it everytime on newly created object instance Newly create dobject inherit the property of the prototype of the constructer function */ /* function Todo(name, age, done) { //console.log(this); this.name = name; this.age = age; this.done = done; } Todo.prototype.getName = function () { console.log(this.name); }; const todo1 = new Todo("khan", 29, true); console.log(todo1); todo1.getName(); */ // Prototypal Ineritance /* The goal is copy over functions and properties from one constructer Function to another Enemy.call(this, life, name, level); we run a call method on Enemy to run the constructor function of Enemy but THIS keyword will refer to Dragon We can create a prototype for the Dragon function and copy (Inherit) the methods from the Enemy Constructor function To inherit the methods to another conbstructor function Dragon.prototype = Object.create(Enemy.prototype); resulting in prototype chain Constructor function and prototyping is somewhat not so cool because we are somewhat trying to emulate classes */ //Enemy constructor function /* function Enemy(life, name, level) { this.life = life; this.name = name; this.level = level; } Enemy.prototype.getInfo = function () { console.log(this.life, this.name, this.level); }; Enemy.prototype.attack = function () { console.log(`${this.name} has attacked`); }; //Dragon constructor function function Dragon(life, name, level, color, spell) { Enemy.call(this, life, name, level); // this will refer to Dragon here this.color = color; this.spell = spell; } //Inhherit Prototype Dragon.prototype = Object.create(Enemy.prototype); Dragon.prototype.fire = function () { console.log("fire"); }; const newDragon = new Dragon(2, "khan", 10, "red", 19); console.log(newDragon); // {life: 2, name: "khan", level: 10, color: "red", spell: 19} newDragon.getInfo(); //2 "khan" 10 newDragon.attack(); //khan has attacked newDragon.fire(); //fire */ //Class /* class is a simple and clean mthod rather than using counstructure function and prototype. instead of using call method , we use super() and extends the class our constructor class to the one we want to inherit */ /* class Enemy { constructor(life, name, level) { this.life = life; this.name = name; this.level = level; } getInfo() { console.log(this.life, this.name, this.level); } attack() { console.log(`${this.name} has attacked`); } } const tiger = new Enemy(2, "Simba", 10); console.log(tiger); tiger.attack(); //Dragon constructor class class Dragon extends Enemy { constructor(life, name, level, color, spell) { super(life, name, level); // this.color = color; this.spell = spell; } fire() { console.log("fire"); } } const newDragon = new Dragon(2, "khan", 10, "red", 19); console.log(newDragon); // {life: 2, name: "khan", level: 10, color: "red", spell: 19} newDragon.getInfo(); //2 "khan" 10 newDragon.attack(); //khan has attacked newDragon.fire(); //fire */