Skip to content

Instantly share code, notes, and snippets.

@m90khan
Last active July 24, 2020 02:30
Show Gist options
  • Save m90khan/6a07c23e215205eeff6deab0704e9cdd to your computer and use it in GitHub Desktop.
Save m90khan/6a07c23e215205eeff6deab0704e9cdd to your computer and use it in GitHub Desktop.

Revisions

  1. m90khan revised this gist Jul 24, 2020. 2 changed files with 198 additions and 144 deletions.
    147 changes: 88 additions & 59 deletions arrays.js
    Original file line number Diff line number Diff line change
    @@ -1,34 +1,49 @@
    // Primitive Datatypes vs Reference Datatypes
    // 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
    - 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
    - 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"];
    // const names = ["Bill"];
    // const newArray = ["khan"];

    // names[0] = "KhanX";
    // names.push(newArray[0]);
    // // names = []; // Uncaught TypeError: Assignment to constant variable.
    // names = []; // Uncaught TypeError: Assignment to constant variable.

    // console.log(names);

    /*
    WHen using LET
    * 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
    - 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);
    */

    //CALLBACK & HIGHER ORDER FUNCTIONS
    // Topic: CALLBACK & HIGHER ORDER FUNCTIONS
    /*
    videos.forEach(function (video) // Function that takes another function as
    aparameter is called higher order function
    */
    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
    * 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 () {
    });
    */

    // MAP FIND FILTER
    // 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)
    /*
    // MAP : Create a copy of the array , loop over it and
    can run a function for modification
    * 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) => {
    console.log(video);
    const mapvideos = videos.map((video, index) => {
    console.log(video, index);
    return video.toUpperCase();
    });
    console.log(videos); //["I love apples","country is just a land","could js take over every application" ];
    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
    /*
    // Find : loop over an array and retrns only the value/string that we are looking for.
    Only the first matched value
    - 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
    /*
    // Filter : loop over an array and retrns all the values/strings that we are looking for.
    - 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);
    */

    // 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
    // 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);
    */

    // Ternary Operator
    // Topic: Ternary Operator
    /*
    More like a If statement
    condition ? do this : else this
    - 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"]
    */

    //Arrow Function
    // Topic:Arrow Function
    /*
    As we use a ton of callback and anonymous function, it is best to use arrow function
    // Nrmal way
    - 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;);
    - 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
    // 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
    - 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} */

    //Copies of Arrays
    // 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
    - 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
    */

    /*
    195 changes: 110 additions & 85 deletions objects.js
    Original file line number Diff line number Diff line change
    @@ -1,38 +1,58 @@
    // Objects
    // Topic: Objects

    //Global Execution and Hoisting
    /*
    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())
    */

    /*
    JS is a single threaded language. meaning the code will run line by line
    //* Global Execution and Hoisting

    - Before code even runs, the JS engine automatically creates global eecuton context
    Creation Phase
    /*
    - 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 objecta memory
    - 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 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
    * 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 doesnot
    // 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");
    // }

    //CallStack
    //Topic: 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
    - 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");
    */

    //This Keyword
    //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
    - 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
    //* Another example
    const userName = {
    name: "ukhano",
    @@ -87,7 +107,7 @@ const admin = {
    };
    function hello() {
    // gives the ability to avoid duplication of code
    //* 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
    // * 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
    - 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
    * 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();
    */

    // 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
    // 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
    * to give access of object to a outside function
    // Bind : to call a methd on a function by passing a reference of the object
    * 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.
    - 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
    * 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
    * 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() {
    // this.getName();
    // }
    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);
    const nameBind = userRegister.bind(person); // bind store the reference to this in userRegister
    nameBind(1, 5);
    // Call
    userRegister.call(person, 1, 7);
    //Apply
    userRegister.apply(person, [1, 7]);
    * 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
    */

    // OOP
    // 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
    - 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
    * 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 {}
    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);
    */

    // Prototype
    // Topic: 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
    - 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
    * 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
    - 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
    - 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);
    console.log(this.name, this.age);
    };
    const todo1 = new Todo("khan", 29, true);
    console.log(todo1);
    todo1.getName();
    todo1.getName();
    */

    // Prototypal Ineritance
    /* The goal is copy over functions and properties from one constructer Function to another
    // 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 conbstructor function Dragon.prototype = Object.create(Enemy.prototype);
    resulting in prototype chain
    - 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
    - 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
    //* 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
    // 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
    */

    //Class
    // 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 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();

    //Dragon constructor class
    //* 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); //
    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
    */
  2. m90khan created this gist Jul 23, 2020.
    37 changes: 37 additions & 0 deletions Constructor.js
    Original 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 });
    });
    313 changes: 313 additions & 0 deletions arrays.js
    Original 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);
    */
    117 changes: 117 additions & 0 deletions async.js
    Original 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();
    39 changes: 39 additions & 0 deletions misc.js
    Original 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");
    // })();
    332 changes: 332 additions & 0 deletions objects.js
    Original 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
    */