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.
javaScript Basics 101 - Part 2
// 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
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);
*/
// 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));
});
// 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`);
});
*/
// 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.
*/
/*
const videos = [
"I love apples",
"HTML5",
"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
*/
/*
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 returns 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);
*/
// 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
*/
/*
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);
*/
// Topic: 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"]
*/
// 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];
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} */
// 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
*/
/*
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);
*/
/* 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();
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 });
});
// 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");
// })();
// 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
*/
/*
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");
*/
//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
*/
/*
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();
*/
// 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();
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(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;
this.getName = function () {
console.log(this.name);
};
}
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);
this.name = name;
this.age = age;
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
*/
//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
*/
// 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;
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();
//* 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;
}
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment