From 730cb5db26d1a056bf28cb1b5fe1bb1307d7c15a Mon Sep 17 00:00:00 2001 From: sohamsshah Date: Wed, 6 Oct 2021 13:17:33 +0530 Subject: [PATCH 01/15] :art: update and clear the clutter --- .../Miscelleneous}/mark_and_sweep.js | 0 JSResourcesite/allinone | 1 - JSResourcesite/javascriptinfo | 1 - UsefulWebsites/README.md | 150 ------------------ buildlogic/que1.js | 35 ---- selfpracticeinterviewquestions/README.md | 74 --------- 6 files changed, 261 deletions(-) rename {Memory Management => DSA/Miscelleneous}/mark_and_sweep.js (100%) delete mode 100644 JSResourcesite/allinone delete mode 100644 JSResourcesite/javascriptinfo delete mode 100644 UsefulWebsites/README.md delete mode 100644 buildlogic/que1.js delete mode 100644 selfpracticeinterviewquestions/README.md diff --git a/Memory Management/mark_and_sweep.js b/DSA/Miscelleneous/mark_and_sweep.js similarity index 100% rename from Memory Management/mark_and_sweep.js rename to DSA/Miscelleneous/mark_and_sweep.js diff --git a/JSResourcesite/allinone b/JSResourcesite/allinone deleted file mode 100644 index 46e7401..0000000 --- a/JSResourcesite/allinone +++ /dev/null @@ -1 +0,0 @@ -https://www.java5cript.com/books \ No newline at end of file diff --git a/JSResourcesite/javascriptinfo b/JSResourcesite/javascriptinfo deleted file mode 100644 index 7601eb4..0000000 --- a/JSResourcesite/javascriptinfo +++ /dev/null @@ -1 +0,0 @@ -https://javascript.info/ \ No newline at end of file diff --git a/UsefulWebsites/README.md b/UsefulWebsites/README.md deleted file mode 100644 index 9caaaf2..0000000 --- a/UsefulWebsites/README.md +++ /dev/null @@ -1,150 +0,0 @@ -### JavaScript:closed_book: - -- YDKJS: A book series on JavaScript - -- Online Interactive JavaScript (JS) Cheat Sheet - -- Cheatsheet for the JavaScript knowledge you will frequently encounter in modern projects - -- Short code snippets for all your development needs - -- What's your favorite JavaScript single LOC (line of code)? - -- 33 concepts every JavaScript developer should know - -- A long list of (advanced) JavaScript questions, and their explanations ✨ - -- EloquentJS: A book about JavaScript, programming, and the wonders of the digital. - -- A list of funny and tricky JavaScript examples🤪 - - -- JavaScript Equality Table - -- A visual playground to JavaScript array & object transformations - -- A re-introduction to JavaScript (JS tutorial) - -- Var, Let, and Const – What's the Difference? - -- ECMAScript 6: Feature Overview & Comparison - -- JavaScript Basics Tutorial - -### ReactJS:blue_book: - -- Cheatsheets for experienced React developers getting started with TypeScript - -- A collection of awesome things regarding React ecosystem - -- List of top 500 ReactJS Interview Questions & Answers - -- Curated List of React Components & Libraries - -- 30-day journey in React - -- Interactive React Lifecycle Methods diagram - -- JavaScript fundamentals before learning React - - -### Redux:ledger: - -- Redux Learning Resources - -- Redux Devtools for Dummies - -- Setting Up Redux DevTools — A Simple Guide - -### GIT:notebook: - - -- Introduction to Git - -- git and git flow cheat sheet - -- Getting Git right, with tutorials, news and tips - -- What is Git - -- 🚀✨ Help beginners to contribute to open source projects - - -### CSS:green_book: - -- CSS CheatSheet - -- 💄CSS tricks for web developers~ - -- A demonstration of what can be accomplished through CSS-based design - -- A game for learning CSS flexbox 🐸 - -- A game for learning CSS grid layout 🥕 - -- Ultimate Flexbox Cheatsheet - -- Ultimate Grid Cheatsheet - -- Can I Use? - -- Box Shadow - -- CSS Values - -- A collection of popular layouts and patterns made with CSS - - -- A collection of tips to help take your CSS skills pro - -- SVG Viewer - -### HTML:orange_book: - -- HTML CheatSheet - -- Learn to Code HTML & CSS by shayhowe - -- Emmet Cheatsheet - -### Backend💻 - -- HTTP Status Codes - -### Productivity🌟 - -- Carbon - Create and share beautiful images of your source code - -- Codesandbox - Code collaboration made easy - -- Coggle Mindmaps - The clear way to share complex information -- Typeracer – the Global Typing Competition -- Learn to Type Faster -- Excalidraw - Virtual whiteboard for sketching hand-drawn like diagrams -- Spotify - Lofi Coders -- Notion - Write, plan, and get organized -- Draw.io - Flowchart Maker and Online Diagram Software - -- Whimsical - Flow Charts, Sticky Notes, MindMaps, Wireframes, Docs - - -### BetterWayOfLearning:books: - -- The Best Way to Learn Frontend Web Development - -- Developers that constantly want to learn new things, here’s a tip! - -- How I Learned to Code and Built a Real Software Product in 6 Months - -- How to Join a Team and Learn a Codebase - - - -### People you must know! - -- [Dan Abramov](https://overreacted.io/) -- [Kent C Dodds](https://kentcdodds.com/) -- [Addy Osmani](https://addyosmani.com/) -- [Eleftheria](https://linktr.ee/eleftheriabatsou) - - diff --git a/buildlogic/que1.js b/buildlogic/que1.js deleted file mode 100644 index 833cac6..0000000 --- a/buildlogic/que1.js +++ /dev/null @@ -1,35 +0,0 @@ -// Create a CLI app which takes name, unit test marks, pre final marks, final marks of 5 students. And then print who has the highest marks. What if I ask you to print the average as well? - - -// add readlineSync package -var readlineSync = require('readline-sync'); - -// array of questions -var questions = ["Enter your name " , "Enter unit test marks " , "Enter preFinal marks " , "Enter final marks "] - -var highest = 0; -var ranker = "" - - -// for loop -for(var i=0; i< 5; i++){ - - var userName = readlineSync.question(questions[0]); - var unitMarks = readlineSync.question(questions[1]); - var preFinal = readlineSync.question(questions[2]); - var final = readlineSync.question(questions[3]); - - var sum = Number(unitMarks) + Number(preFinal) + Number(final) - - var avg = (sum) / 3 - - console.log(userName + " your Average marks from all three test is " + avg) - -if(sum > highest){ - highest = sum - ranker = userName -} -} - -console.log("Highest scorer is: " + ranker + " whose total is: " + highest) - diff --git a/selfpracticeinterviewquestions/README.md b/selfpracticeinterviewquestions/README.md deleted file mode 100644 index 474137d..0000000 --- a/selfpracticeinterviewquestions/README.md +++ /dev/null @@ -1,74 +0,0 @@ -# Here I am listing some good javascript questions to practice - -# Easy - - 1. Given a and b, your function should return the value of ab -Example: -Input: power(2,3) ––> Output: 8 - -2. Given length of a regular hexagon, your function should return area of the hexagon. -Example: -Input: areaOfHexagon(10) ––> Output: 259.80 - -3. Given a sentence, your functions should return the number of words in the sentence. -Example: -Input: noOfWords(We are neoGrammers) ––> Output: 3 - -4. Given n numbers, your function should return the minimum of them all. The number of parameters won't be accepted from user. -Example: -Input: findMin(3,5) ––> Output: 3 -Input: findMin(3,5,9,1) ––> Output: 1 -(Hint: Lookup rest parameters in JavaScript) - -5. Given n numbers, your function should return the maximum of them all. The number of parameters won't be accepted from user. -Example: -Input: findMax(3,5) ––> Output: 5 -Input: findMax(3,5,9,1) ––> Output: 9 -(Hint: Lookup rest parameters in JavaScript) - -6. Given three angles of a triange, your function should return if it is a scalen, isosceles, equilateral triangle or not a triangle at all. Example: -Input: typeOfTriangle(30, 60, 90) ––> Output: Scalen Triangle - -# Medium - -7. Given an array, your function should return the length of the array. -Example: -Input: arrayLength([1,5,3,7,8]) ––> Output: 5 - -8. Given an array and an item, your function should return the index at which the item is present. -Example: -Input: indexOf([1,6,3,5,8,9], 3) ––> Output: 2 - -9. Given an array and two numbers, your function should replace all entries of first number in an array with the second number. -Example: -Input: replace([1,5,3,5,6,8], 5, 10) ––> Output: [1,10,3,10,6,8] - -10. Given two arrays, your function should return single merged array. -Example: -Input: mergeArray([1,3,5], [2,4,6]) ––> Output: [1,3,5,2,4,6] - -11. Given a string and an index, your function should return the character present at that index in the string. -Example: -Input: charAt("neoGcamp", 4) ––> Output: c - -12. Given two dates, your function should return which one comes before the other. -Example: -Input: minDate('02/05/2021', '24/01/2021') ––> Output: 24/01/2021 - -# Advanced - -13. Write a function which generates a secret code from a given string, by shifting characters of alphabet by N places. Example: -Input: encodeString("neogcamp", 2) ––> Output: pgqiecor -Explanation: 2 represents shifting alphabets by 2 places. a –> c, b –> d, c –> e and so on. - -14. Given a sentence, return a sentence with first letter of all words as capital. -Example: -Input: toSentenceCase('we are neoGrammers') ––> Output: We Are NeoGrammers - -15. Given an array of numbers, your function should return an array in the ascending order. -Example: -Input: sortArray([100,83,32,9,45,61]) ––> Output: [9,32,45,61,83,100] - -16. Given a sentence, your function should reverse the order of characters in each word, keeping same sequence of words. -Example: -Input: reverseCharactersOfWord('we are neoGrammers') –––> Output: ew era sremmarGoen From 87d78c1539725394c29a5e02b88af50cbe8f5f07 Mon Sep 17 00:00:00 2001 From: sohamsshah Date: Wed, 6 Oct 2021 13:30:56 +0530 Subject: [PATCH 02/15] :memo: improve README.md --- README.md | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index dc8a2d7..f0dd535 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,38 @@ # < JavaScriptONLY />👨‍💻 🙏 -### Its an attempt to provide high quality, well-written set of notes for anyone who wants to learn and refer JavaScript concepts in deep. +### Its an attempt to provide high quality, well-written set of notes and code-snippets for anyone who wants to learn and refer JavaScript concepts in deep. + +--- ----- #### This repository will be your go-to place when you feel to write better and cleaner code for your project, want to debug without frustration and cursing JS or to praise the beauty of this language in real sense. + --- > JavaScript is Beautiful ♥. But it takes the eyes of the coder to admire ~ *anonymous*✨ --- -### __We love Contributions💖__: + +### **We love Contributions💖**: + Feel free to create an issue about what topic you want to add explanations or code snippets that covers core JS concepts in a better and lucid way. Link a PR with it and we are ready to accept your contributions! Refer [this](https://github.com/sohamsshah/JavaScriptONLY/blob/master/CONTRIBUTING.md) for more insights. +### How can I contribute? + +- If you are into Data Structures and Algorithms ft. JavaScript, contribute by adding your favourite ones to [here](/DSA) +- If you are practicing JavaScript Interview Questions, share your approach and learnings [here](/InterviewQuestions) +- Have got Code Snippets in JavaScript? Dump them in [here](/Snippets) +- Love taking Notes? We are looking for contributions to [NamasteJS](/NamasteJS) and [EloquentJS](/EloquentJS) currently! +- Into Documentation? Presently, a lot of code isn't well documented. We need to maintain a README.md for each sections! Help will be appreciated there. +- Feel Free to Raise Issues and create PRs :) + --- + ### Contributors💻: -As always, thanks to our amazing contributors who are making the world fall in love with JavaScript 💛! + +As always, thanks to our amazing contributors who are making the world fall in love with JavaScript 💛! - --- - - From 2d17c45b3d0787ca673c25afc2de586c88557d2c Mon Sep 17 00:00:00 2001 From: Soham Shah Date: Sat, 21 May 2022 00:07:14 +0530 Subject: [PATCH 03/15] feat: add prototype, promises code snippets --- Snippets/Prototype/basic.js | 29 +++++++++++++ Snippets/Prototype/forInLoop.js | 25 +++++++++++ Snippets/Prototype/getAndset.js | 25 +++++++++++ Snippets/Prototype/nativePrototypes.js | 23 ++++++++++ Snippets/Prototype/prototype.js | 35 +++++++++++++++ Snippets/Prototype/searchingAlgorithm.js | 34 +++++++++++++++ Snippets/Prototype/this.js | 22 ++++++++++ Snippets/Prototype/whyAreBothHamstersFull.js | 45 ++++++++++++++++++++ 8 files changed, 238 insertions(+) create mode 100644 Snippets/Prototype/basic.js create mode 100644 Snippets/Prototype/forInLoop.js create mode 100644 Snippets/Prototype/getAndset.js create mode 100644 Snippets/Prototype/nativePrototypes.js create mode 100644 Snippets/Prototype/prototype.js create mode 100644 Snippets/Prototype/searchingAlgorithm.js create mode 100644 Snippets/Prototype/this.js create mode 100644 Snippets/Prototype/whyAreBothHamstersFull.js diff --git a/Snippets/Prototype/basic.js b/Snippets/Prototype/basic.js new file mode 100644 index 0000000..24921f0 --- /dev/null +++ b/Snippets/Prototype/basic.js @@ -0,0 +1,29 @@ +let arr = ["Soham", "Dhruvi"]; + +let obj = { + name: "Soham", + city: "Ahmedabad", + getIntro: function () { + console.log(this.name + "from" + this.city); + }, +}; + +function fun() { + console.log("hello"); +} + +/* +Learnings +arr.__proto__ === Array.prototype +arr.__proto__.__proto__ === Object.prototype +arr.__proto__.__proto__ === null + +obj.__proto__ === Object.prototype +obj.__proto__proto__ === null + +fun.__proto__ === Function.prototype +fun.__proto__.__proto__ === Object.prototype +fun.__proto__.__proto__.__prototype === null + +Everything is object in JavaScript +*/ diff --git a/Snippets/Prototype/forInLoop.js b/Snippets/Prototype/forInLoop.js new file mode 100644 index 0000000..2c716a9 --- /dev/null +++ b/Snippets/Prototype/forInLoop.js @@ -0,0 +1,25 @@ +let animal = { + eats: true, +}; + +let rabbit = { + jumps: true, + __proto__: animal, +}; + +// Object.keys only returns own keys +console.log(Object.keys(rabbit)); // jumps + +// for..in loops over both own and inherited keys +for (let prop in rabbit) console.log(prop); // jumps, then eats + +// only loop in own keys and ignore inherited keys +for (let prop in rabbit) { + let isOwn = rabbit.hasOwnProperty(prop); + + if (isOwn) { + alert(`Our: ${prop}`); // Our: jumps + } else { + alert(`Inherited: ${prop}`); // Inherited: eats + } +} diff --git a/Snippets/Prototype/getAndset.js b/Snippets/Prototype/getAndset.js new file mode 100644 index 0000000..8b7964b --- /dev/null +++ b/Snippets/Prototype/getAndset.js @@ -0,0 +1,25 @@ +let user = { + name: "John", + surname: "Smith", + + set fullName(value) { + [this.name, this.surname] = value.split(" "); + }, + + get fullName() { + return `${this.name} ${this.surname}`; + }, +}; + +let admin = { + __proto__: user, + isAdmin: true, +}; + +console.log(admin.fullName); // John Smith + +// setter triggers! +admin.fullName = "Alice Cooper"; + +console.log(admin.fullName); // Alice Cooper, state of admin modified +console.log(user.fullName); // John Smith, state of user protected diff --git a/Snippets/Prototype/nativePrototypes.js b/Snippets/Prototype/nativePrototypes.js new file mode 100644 index 0000000..48db9fd --- /dev/null +++ b/Snippets/Prototype/nativePrototypes.js @@ -0,0 +1,23 @@ +Function.prototype.defer = function (ms) { + setTimeout(this, ms); +}; + +function f() { + console.log("Hello!"); +} + +f.defer(1000); // shows "Hello!" after 1 sec + +Function.prototype.defer2 = function (ms) { + let k = this; + return function (...args) { + setTimeout(() => k.apply(this, args), ms); + }; +}; + +// check it +function k(a, b) { + console.log(a + b); +} + +k.defer(1000)(1, 2); // shows 3 after 1 sec diff --git a/Snippets/Prototype/prototype.js b/Snippets/Prototype/prototype.js new file mode 100644 index 0000000..14e0e12 --- /dev/null +++ b/Snippets/Prototype/prototype.js @@ -0,0 +1,35 @@ +let animal = { + eats: true, +}; + +function Rabbit(name) { + this.name = name; +} + +Rabbit.prototype = animal; + +let rabbit = new Rabbit("White Rabbit"); // rabbit.__proto__ == animal + +let rabbit2 = new rabbit.constructor("Black Rabbit"); // another way to create a new object + +// re-assigning prototype of Rabbit +Rabbit.prototype = { + jumps: true, +}; + +let rabbit3 = new Rabbit(); +console.log(rabbit.constructor === Rabbit); // false + +// Not overwrite Rabbit.prototype totally +// just add to it +Rabbit.prototype.jumps = true; +// the default Rabbit.prototype.constructor is preserved + +let rabbit4 = new Rabbit(); +console.log(rabbit.constructor === Rabbit); // false + +// Other alternative way +Rabbit.prototype = { + jumps: true, + constructor: Rabbit, +}; diff --git a/Snippets/Prototype/searchingAlgorithm.js b/Snippets/Prototype/searchingAlgorithm.js new file mode 100644 index 0000000..04b89df --- /dev/null +++ b/Snippets/Prototype/searchingAlgorithm.js @@ -0,0 +1,34 @@ +/* +Problem statement +Use __proto__ to assign prototypes in a way that any property lookup will follow the path: pockets → bed → table → head. For instance, pockets.pen should be 3 (found in table), and bed.glasses should be 1 (found in head). +Answer the question: is it faster to get glasses as pockets.glasses or head.glasses? Benchmark if needed. +*/ + +let head = { + glasses: 1, +}; + +let table = { + pen: 3, + __proto__: head, +}; + +let bed = { + sheet: 1, + pillow: 2, + __proto__: table, +}; + +let pockets = { + money: 2000, + __proto__: bed, +}; + +console.log(pockets.pen); // 3 +console.log(bed.glasses); // 1 + +/* +In modern engines, performance-wise, there’s no difference whether we take a property from an object or its prototype. They remember where the property was found and reuse it in the next request. + +For instance, for pockets.glasses they remember where they found glasses (in head), and next time will search right there. They are also smart enough to update internal caches if something changes, so that optimization is safe. +*/ diff --git a/Snippets/Prototype/this.js b/Snippets/Prototype/this.js new file mode 100644 index 0000000..2f4508f --- /dev/null +++ b/Snippets/Prototype/this.js @@ -0,0 +1,22 @@ +// animal has methods +let animal = { + walk() { + if (!this.isSleeping) { + console.log(`I walk`); + } + }, + sleep() { + this.isSleeping = true; + }, +}; + +let rabbit = { + name: "White Rabbit", + __proto__: animal, +}; + +// modifies rabbit.isSleeping +rabbit.sleep(); + +console.log(rabbit.isSleeping); // true +console.log(animal.isSleeping); // undefined (no such property in the prototype) diff --git a/Snippets/Prototype/whyAreBothHamstersFull.js b/Snippets/Prototype/whyAreBothHamstersFull.js new file mode 100644 index 0000000..dc3059f --- /dev/null +++ b/Snippets/Prototype/whyAreBothHamstersFull.js @@ -0,0 +1,45 @@ +let hamster = { + stomach: [], + eat(food) { + this.stomach.push(food); + }, +}; + +let speedy = { + __proto__: hamster, +}; + +let lazy = { + __proto__: hamster, +}; + +// This one found the food +speedy.eat("apple"); +console.log(speedy.stomach); // apple + +// This one also has it, why? +console.log(lazy.stomach); // apple + +/* +Reason: + +speedy.eat() -> couldn't find in its obj -> finds it in hamster +Now, this = speedy +In this.stomach.push() -> it searches for stomach value -> couldn't find in speedy -> found in hamster +So, this.stomach.push actually pushes food to the hamster object's stomach; which is common for both of them +*/ + +/* +Solution: + +let speedy = { + __proto__: hamster, + stomach: [] +}; + +let lazy = { + __proto__: hamster, + stomach: [] +}; + +*/ From 9af0f6c7061b69a845effd324db8a040a68f868f Mon Sep 17 00:00:00 2001 From: Soham Shah Date: Sat, 21 May 2022 00:08:11 +0530 Subject: [PATCH 04/15] feat: add prototype, promises code snippets --- Snippets/Promises/asyncAwait.js | 21 ++++++++ Snippets/Promises/callAsyncFromNonAsync.js | 12 +++++ Snippets/Promises/microtask.js | 11 ++++ .../noNeedToReturnPromiseInThenChain.js | 11 ++++ Snippets/Promises/promiseAPI.js | 20 ++++++++ Snippets/Promises/resolveVsReturn.js | 17 +++++++ Snippets/Promises/retryNTimes.js | 51 +++++++++++++++++++ .../throwingErrorOutsidePromiseChain.js | 14 +++++ Snippets/Promises/tryCatch.js | 20 ++++++++ 9 files changed, 177 insertions(+) create mode 100644 Snippets/Promises/asyncAwait.js create mode 100644 Snippets/Promises/callAsyncFromNonAsync.js create mode 100644 Snippets/Promises/microtask.js create mode 100644 Snippets/Promises/noNeedToReturnPromiseInThenChain.js create mode 100644 Snippets/Promises/promiseAPI.js create mode 100644 Snippets/Promises/resolveVsReturn.js create mode 100644 Snippets/Promises/retryNTimes.js create mode 100644 Snippets/Promises/throwingErrorOutsidePromiseChain.js create mode 100644 Snippets/Promises/tryCatch.js diff --git a/Snippets/Promises/asyncAwait.js b/Snippets/Promises/asyncAwait.js new file mode 100644 index 0000000..82a5a24 --- /dev/null +++ b/Snippets/Promises/asyncAwait.js @@ -0,0 +1,21 @@ +function loadJson(url) { + return fetch(url).then((response) => { + if (response.status == 200) { + return response.json(); + } else { + throw new Error(response.status); + } + }); +} + +loadJson("https://javascript.info/no-such-user.json").catch(alert); // Error: 404 + +async function loadJsonAsyncAwait(url) { + const response = await fetch(url); + if (response.status === 200) { + return response.json(); + } + throw new Error(response.status); +} + +loadJsonAsyncAwait("https://javascript.info/no-such-user.json").catch(alert); // Error: 404 diff --git a/Snippets/Promises/callAsyncFromNonAsync.js b/Snippets/Promises/callAsyncFromNonAsync.js new file mode 100644 index 0000000..d06f398 --- /dev/null +++ b/Snippets/Promises/callAsyncFromNonAsync.js @@ -0,0 +1,12 @@ +async function wait() { + await new Promise((resolve) => setTimeout(resolve, 3000)); + + return 10; +} + +function f() { + // get value from the promise by calling async code in sync func + wait().then((value) => console.log(value)); +} + +f(); diff --git a/Snippets/Promises/microtask.js b/Snippets/Promises/microtask.js new file mode 100644 index 0000000..e1b2397 --- /dev/null +++ b/Snippets/Promises/microtask.js @@ -0,0 +1,11 @@ +const a = "5"; +const promise = new Promise((resolve, reject) => { + setTimeout(() => resolve(1), 3000); + console.log("Inside promise"); // 1 +}); + +promise.then((val) => console.log("Promise", val)); // 3 + +setTimeout(() => console.log("Set Timeout ran"), 3000); // 4 + +console.log(a); // 2 diff --git a/Snippets/Promises/noNeedToReturnPromiseInThenChain.js b/Snippets/Promises/noNeedToReturnPromiseInThenChain.js new file mode 100644 index 0000000..99e2144 --- /dev/null +++ b/Snippets/Promises/noNeedToReturnPromiseInThenChain.js @@ -0,0 +1,11 @@ +function first(num) { + return Promise.resolve(num); // starting the then chain by returning a promise +} + +function second(num) { + return num + 1; // no need to return promise as this function is in 'then' chain +} + +first(4) + .then((valueOne) => second(valueOne)) + .then((valueTwo) => console.log(valueTwo)); diff --git a/Snippets/Promises/promiseAPI.js b/Snippets/Promises/promiseAPI.js new file mode 100644 index 0000000..c19513b --- /dev/null +++ b/Snippets/Promises/promiseAPI.js @@ -0,0 +1,20 @@ +/* +There are 6 static methods of Promise class: + +Promise.all(promises) – waits for all promises to resolve and returns an array of their results. If any of the given promises rejects, it becomes the error of Promise.all, and all other results are ignored. +Promise.allSettled(promises) (recently added method) – waits for all promises to settle and returns their results as an array of objects with: +status: "fulfilled" or "rejected" +value (if fulfilled) or reason (if rejected). +Promise.race(promises) – waits for the first promise to settle, and its result/error becomes the outcome. +Promise.any(promises) (recently added method) – waits for the first promise to fulfill, and its result becomes the outcome. If all of the given promises are rejected, AggregateError becomes the error of Promise.any. +Promise.resolve(value) – makes a resolved promise with the given value. +Promise.reject(error) – makes a rejected promise with the given error. + +*/ +Promise.race([ + new Promise((resolve, reject) => setTimeout(() => resolve(1), 1000)), + new Promise((resolve, reject) => + setTimeout(() => reject(new Error("Whoops!")), 2000) + ), + new Promise((resolve, reject) => setTimeout(() => resolve(3), 3000)), +]).then((value) => console.log(value)); diff --git a/Snippets/Promises/resolveVsReturn.js b/Snippets/Promises/resolveVsReturn.js new file mode 100644 index 0000000..1cf7ee7 --- /dev/null +++ b/Snippets/Promises/resolveVsReturn.js @@ -0,0 +1,17 @@ +function second() { + return new Promise((resolve, reject) => { + // resolve/reject happens only one time + resolve(1); + reject("Failed"); + resolve(2); + console.log("After resolve/reject"); // this will be printed first because aLl lines will be executed + }); +} + +function first() { + second() + .then((value) => console.log(value)) + .catch((err) => console.log(err)); +} + +first(); diff --git a/Snippets/Promises/retryNTimes.js b/Snippets/Promises/retryNTimes.js new file mode 100644 index 0000000..d244d18 --- /dev/null +++ b/Snippets/Promises/retryNTimes.js @@ -0,0 +1,51 @@ +// wait function +const wait = (ms) => { + return new Promise((resolve) => { + setTimeout(() => resolve(), ms); + }); +}; + +const retryWithDelay = ( + operation, + retries = 3, + delay = 50, + finalErr = "Retry Failed" +) => { + return new Promise((resolve, reject) => + operation() + .then(resolve) + .catch((reason) => { + console.log(retries); + if (retries > 0) { + return wait(delay) + .then( + retryWithDelay.bind(null, operation, retries - 1, delay, finalErr) + ) + .then(resolve) + .catch(reject); + } + // throw final error + return reject(finalErr); + }) + ); +}; + +const getTestFunc = () => { + let callCounter = 0; + return async () => { + callCounter += 1; + + if (callCounter) { + throw new Error("Not yet"); + } + }; +}; + +// Test the code +const test = async () => { + await retryWithDelay(getTestFunc(), 10, 1000); + console.log("success"); +}; + +// Print the result +test().catch(console.error); diff --git a/Snippets/Promises/throwingErrorOutsidePromiseChain.js b/Snippets/Promises/throwingErrorOutsidePromiseChain.js new file mode 100644 index 0000000..53327b0 --- /dev/null +++ b/Snippets/Promises/throwingErrorOutsidePromiseChain.js @@ -0,0 +1,14 @@ +function first() { + throw new Error("lol"); // error wont be caught in .catch() + return Promise.resolve(1); +} + +function second(num) { + throw new Error("lol"); // error will be caught in .catch() + return num + 2; +} + +first() + .then((valueOne) => second(valueOne)) + .then((valueTwo) => console.log(valueTwo)) + .catch((err) => console.log(err)); diff --git a/Snippets/Promises/tryCatch.js b/Snippets/Promises/tryCatch.js new file mode 100644 index 0000000..21625d8 --- /dev/null +++ b/Snippets/Promises/tryCatch.js @@ -0,0 +1,20 @@ +async function first() { + try { + // return await second(); // remains synchronous for the function if used await + return second(); //asynchronous returning the function + } catch (err) { + console.log("Try/Catch", err); + } +} + +function second() { + return Promise.reject("Something went wrong!"); +} + +first() + .then(() => { + console.log("End"); + }) + .catch((err) => { + console.log("From .catch()", err); + }); From 8ef77d6bfcedeb28345bb8aa8689304495224703 Mon Sep 17 00:00:00 2001 From: Soham Shah Date: Fri, 27 May 2022 12:17:22 +0530 Subject: [PATCH 05/15] feat: add functions, objects, recursion etc. snippets --- Snippets/Functions/call.js | 27 ++++++++++ Snippets/Functions/customSetInterval.js | 15 ++++++ Snippets/Functions/debounceDecorator.js | 18 +++++++ Snippets/Functions/delayDecorator.js | 18 +++++++ Snippets/Functions/makeCounter.js | 24 +++++++++ Snippets/Functions/multiArgumentCaching.js | 30 +++++++++++ Snippets/Functions/namedFunctionExpression.js | 12 +++++ Snippets/Functions/nestedSetTimeout.js | 12 +++++ Snippets/Functions/newFunctionSyntax.js | 7 +++ Snippets/Functions/outputEverySecond.js | 50 +++++++++++++++++++ Snippets/Functions/polymorphism.js | 19 +++++++ Snippets/Functions/properties.js | 48 ++++++++++++++++++ Snippets/Functions/setInterval.js | 4 ++ Snippets/Functions/setTimeout.js | 20 ++++++++ Snippets/Functions/spyDecorator.js | 29 +++++++++++ .../sumWithArbitaryAmountOfBrackets.js | 32 ++++++++++++ Snippets/Functions/throttleDecorator.js | 19 +++++++ Snippets/Functions/transparentCaching.js | 26 ++++++++++ 18 files changed, 410 insertions(+) create mode 100644 Snippets/Functions/call.js create mode 100644 Snippets/Functions/customSetInterval.js create mode 100644 Snippets/Functions/debounceDecorator.js create mode 100644 Snippets/Functions/delayDecorator.js create mode 100644 Snippets/Functions/makeCounter.js create mode 100644 Snippets/Functions/multiArgumentCaching.js create mode 100644 Snippets/Functions/namedFunctionExpression.js create mode 100644 Snippets/Functions/nestedSetTimeout.js create mode 100644 Snippets/Functions/newFunctionSyntax.js create mode 100644 Snippets/Functions/outputEverySecond.js create mode 100644 Snippets/Functions/polymorphism.js create mode 100644 Snippets/Functions/properties.js create mode 100644 Snippets/Functions/setInterval.js create mode 100644 Snippets/Functions/setTimeout.js create mode 100644 Snippets/Functions/spyDecorator.js create mode 100644 Snippets/Functions/sumWithArbitaryAmountOfBrackets.js create mode 100644 Snippets/Functions/throttleDecorator.js create mode 100644 Snippets/Functions/transparentCaching.js diff --git a/Snippets/Functions/call.js b/Snippets/Functions/call.js new file mode 100644 index 0000000..76fc2eb --- /dev/null +++ b/Snippets/Functions/call.js @@ -0,0 +1,27 @@ +"use strict"; +let worker = { + someMethod() { + return 1; + }, + slow(x) { + console.log("Called with", x); + return x + this.someMethod(); // need a reference for this + }, +}; + +function cachingDecorator(func) { + const cache = new Map(); + return function (x) { + if (cache.has(x)) { + return cache.get(x); + } + const res = func.call(this, x); + cache.set(x, res); + return res; + }; +} + +worker.slow = cachingDecorator(worker.slow); // now make it caching + +console.log(worker.slow(2)); // works +console.log(worker.slow(2)); // works, doesn't call the original (cached) diff --git a/Snippets/Functions/customSetInterval.js b/Snippets/Functions/customSetInterval.js new file mode 100644 index 0000000..a3a7080 --- /dev/null +++ b/Snippets/Functions/customSetInterval.js @@ -0,0 +1,15 @@ +const mySetInterval = (callback, delay, ...args) => { + let timerId = setTimeout( + function tick(...args) { + callback(...args); + timerId = setTimeout(tick, delay, ...args); + }, + delay, + ...args + ); +}; + +function cb(x, y) { + console.log(x, y); +} +mySetInterval(cb, 2000, 1, 2); diff --git a/Snippets/Functions/debounceDecorator.js b/Snippets/Functions/debounceDecorator.js new file mode 100644 index 0000000..a3381c4 --- /dev/null +++ b/Snippets/Functions/debounceDecorator.js @@ -0,0 +1,18 @@ +function debounce(func, delay) { + let timeout; + return function (...args) { + if (timeout) { + clearTimeout(timeout); + } + timeout = setTimeout(() => { + func(...args); + // func.apply(this, args) + }, delay); + }; +} + +let f = debounce(console.log, 2000); + +f("a"); +setTimeout(() => f("b"), 200); +setTimeout(() => f("c"), 500); diff --git a/Snippets/Functions/delayDecorator.js b/Snippets/Functions/delayDecorator.js new file mode 100644 index 0000000..ba21328 --- /dev/null +++ b/Snippets/Functions/delayDecorator.js @@ -0,0 +1,18 @@ +function f(x) { + console.log(x); +} + +function delay(func, delay) { + return function (...args) { + setTimeout(() => { + func.call(this, ...args); + }, delay); + }; +} + +// create wrappers +let f1000 = delay(f, 1000); +let f1500 = delay(f, 1500); + +f1000("test"); // shows "test" after 1000ms +f1500("test"); // shows "test" after 1500ms diff --git a/Snippets/Functions/makeCounter.js b/Snippets/Functions/makeCounter.js new file mode 100644 index 0000000..1d90f60 --- /dev/null +++ b/Snippets/Functions/makeCounter.js @@ -0,0 +1,24 @@ +const makeCounter = () => { + const counter = () => { + return counter.count++; + }; + counter.set = (val) => { + counter.count = val; + return counter.count; + }; + + counter.decrease = () => { + counter.count--; + return counter.count; + }; + + counter.count = 0; + + return counter; +}; + +const counter = makeCounter(); + +console.log(counter()); +console.log(counter.set(10)); +console.log(counter.decrease()); diff --git a/Snippets/Functions/multiArgumentCaching.js b/Snippets/Functions/multiArgumentCaching.js new file mode 100644 index 0000000..33618d6 --- /dev/null +++ b/Snippets/Functions/multiArgumentCaching.js @@ -0,0 +1,30 @@ +const worker = { + slow(min, max) { + console.log(`Called with ${min},${max}`); + return min + max; + }, +}; + +function cachingDecorator(func, hash) { + const cache = new Map(); + return function (...args) { + let key = hash(args); + if (cache.has(key)) { + return cache.get(key); + } + let res = func.apply(this, args); + // or let res = func.call(this, ...args) + cache.set(key, res); + return res; + }; +} + +function hash(args) { + // [].join.call(arguments) + return args.join(); +} + +worker.slow = cachingDecorator(worker.slow, hash); + +console.log(worker.slow(3, 5)); // works +console.log("Again " + worker.slow(3, 5)); // same (cached) diff --git a/Snippets/Functions/namedFunctionExpression.js b/Snippets/Functions/namedFunctionExpression.js new file mode 100644 index 0000000..1adfb70 --- /dev/null +++ b/Snippets/Functions/namedFunctionExpression.js @@ -0,0 +1,12 @@ +let sayHi = function func(who) { + if (who) { + console.log(`Hello, ${who}`); + } else { + func("Guest"); // Error: sayHi is not a function + } +}; + +let welcome = sayHi; +sayHi = null; + +welcome(); // Error, the nested sayHi call doesn't work any more! diff --git a/Snippets/Functions/nestedSetTimeout.js b/Snippets/Functions/nestedSetTimeout.js new file mode 100644 index 0000000..7bbe30d --- /dev/null +++ b/Snippets/Functions/nestedSetTimeout.js @@ -0,0 +1,12 @@ +let delay = 5000; + +let timerId = setTimeout(function request() { + console.log("Send Request to server", delay); + if (true) { + // request failed due to server overload + // increase the interval to the next run + delay *= 2; + } + + timerId = setTimeout(request, delay); +}, delay); diff --git a/Snippets/Functions/newFunctionSyntax.js b/Snippets/Functions/newFunctionSyntax.js new file mode 100644 index 0000000..217d9e2 --- /dev/null +++ b/Snippets/Functions/newFunctionSyntax.js @@ -0,0 +1,7 @@ +let sum = new Function("a", "b", "return a + b"); + +alert(sum(1, 2)); // 3 + +let sayHi = new Function('alert("Hello")'); + +sayHi(); // Hello diff --git a/Snippets/Functions/outputEverySecond.js b/Snippets/Functions/outputEverySecond.js new file mode 100644 index 0000000..50f4306 --- /dev/null +++ b/Snippets/Functions/outputEverySecond.js @@ -0,0 +1,50 @@ +function printNumbers(from, to) { + const timerId = setInterval( + function f(to) { + console.log(from); + if (to === from) { + clearInterval(timerId); + } + from = from + 1; + }, + 1000, + to + ); +} + +printNumbers(1, 10); + +// with nested setTimeout + +function printNumbers(from, to) { + let current = from; + + setTimeout(function go() { + alert(current); + if (current < to) { + setTimeout(go, 1000); + } + current++; + }, 1000); +} + +// usage: +printNumbers(5, 10); + +// runs immediately +function printNumbers(from, to) { + let current = from; + + function go() { + alert(current); + if (current == to) { + clearInterval(timerId); + } + current++; + } + + go(); + let timerId = setInterval(go, 1000); +} + +printNumbers(5, 10); diff --git a/Snippets/Functions/polymorphism.js b/Snippets/Functions/polymorphism.js new file mode 100644 index 0000000..a218e64 --- /dev/null +++ b/Snippets/Functions/polymorphism.js @@ -0,0 +1,19 @@ +function ask(question, ...handlers) { + let isYes = confirm(question); + + for (let handler of handlers) { + if (handler.length == 0) { + if (isYes) handler(); + } else { + handler(isYes); + } + } +} + +// for positive answer, both handlers are called +// for negative answer, only the second one +ask( + "Question?", + () => alert("You said yes"), + (result) => alert(result) +); diff --git a/Snippets/Functions/properties.js b/Snippets/Functions/properties.js new file mode 100644 index 0000000..3ebcb14 --- /dev/null +++ b/Snippets/Functions/properties.js @@ -0,0 +1,48 @@ +function sayHi() { + console.log("Hi"); +} + +console.log(sayHi.name); +console.log(function () {}.name); // empty string + +function f1(a) {} +function f2(a, b) {} +function many(a, b, ...more) {} + +console.log(f1.length); // 1 +console.log(f2.length); // 2 +console.log(many.length); // 2 + +// custom property + +function sayHi() { + console.log("Hi"); + + // let's count how many times we run + sayHi.counter++; +} +sayHi.counter = 0; // initial value + +sayHi(); // Hi +sayHi(); // Hi + +console.log(`Called ${sayHi.counter} times`); // Called 2 times + +// counter with custom property + +function makeCounter() { + // instead of: + // let count = 0 + + function counter() { + return counter.count++; + } + + counter.count = 0; + + return counter; +} + +let counter = makeCounter(); +alert(counter()); // 0 +alert(counter()); // 1 diff --git a/Snippets/Functions/setInterval.js b/Snippets/Functions/setInterval.js new file mode 100644 index 0000000..40e0b84 --- /dev/null +++ b/Snippets/Functions/setInterval.js @@ -0,0 +1,4 @@ +// let timerId = setInterval(func|code, [delay], [arg1], [arg2], ...) + +// repeat with the interval of 2 seconds +let timerId = setInterval(() => alert("tick"), 2000); diff --git a/Snippets/Functions/setTimeout.js b/Snippets/Functions/setTimeout.js new file mode 100644 index 0000000..7983b60 --- /dev/null +++ b/Snippets/Functions/setTimeout.js @@ -0,0 +1,20 @@ +// let timerId = setTimeout(func|code, [delay], [arg1], [arg2], ...) + +function sayHi(phrase, who) { + alert(phrase + ", " + who); +} + +setTimeout(sayHi, 1000, "Hello", "John"); // Hello, John + +// string also works +setTimeout("alert('Hello')", 1000); + +// recommended +setTimeout(() => alert("Hello"), 1000); + +// wrong! +setTimeout(sayHi(), 1000); + +// clear timeout +let timerId = setTimeout(() => alert("Hi")); +clearTimeout(timerId); diff --git a/Snippets/Functions/spyDecorator.js b/Snippets/Functions/spyDecorator.js new file mode 100644 index 0000000..0d769cd --- /dev/null +++ b/Snippets/Functions/spyDecorator.js @@ -0,0 +1,29 @@ +function work(a, b) { + console.log(a + b); // work is an arbitrary function or method +} + +function spy(func) { + wrapper.calls = []; + function wrapper(...args) { + const key = hash(args); + func.call(this, ...args); + wrapper.calls.push(key); + } + + return wrapper; +} + +const hash = (args) => { + return args.join(); +}; + +work = spy(work); + +work(1, 2); // 3 +work(4, 5); // 9 + +console.log(work); + +for (let args of work.calls) { + console.log("call:" + args); // "call:1,2", "call:4,5" +} diff --git a/Snippets/Functions/sumWithArbitaryAmountOfBrackets.js b/Snippets/Functions/sumWithArbitaryAmountOfBrackets.js new file mode 100644 index 0000000..5ce5198 --- /dev/null +++ b/Snippets/Functions/sumWithArbitaryAmountOfBrackets.js @@ -0,0 +1,32 @@ +const sum = (x) => { + let total = x; + return function by(y) { + if (y === undefined) { + return total; + } else { + total += y; + return by; + } + }; +}; + +console.log(sum(1)(2)(5)()); + +// But what if we need exactly like this: sum(1)(2)(5) for the result +function sum(a) { + let currentSum = a; + + function f(b) { + currentSum += b; + return f; + } + + f.toString = function () { + return currentSum; + }; + + return f; +} + +const val = sum(1)(8); // 3 +alert(val); // alert calls val.toString(). We can modify this function for our use case diff --git a/Snippets/Functions/throttleDecorator.js b/Snippets/Functions/throttleDecorator.js new file mode 100644 index 0000000..fbc0daf --- /dev/null +++ b/Snippets/Functions/throttleDecorator.js @@ -0,0 +1,19 @@ +function throttle(func, delay) { + let flag = true; + return function (...args) { + if (flag) { + flag = false; + setTimeout(() => { + func.apply(this, args); + flag = true; + }); + } + }; +} + +const f = (text) => { + console.log(text); +}; + +const f1000 = throttle(f, 1000); +f1000("Hi I am 1000s throttle function"); diff --git a/Snippets/Functions/transparentCaching.js b/Snippets/Functions/transparentCaching.js new file mode 100644 index 0000000..ef3f4a2 --- /dev/null +++ b/Snippets/Functions/transparentCaching.js @@ -0,0 +1,26 @@ +const delay = (data, ms) => { + setTimeout(() => console.log("computing", data), ms); +}; +let slow = async (x) => { + await delay(x, 3000); + return x; +}; + +const cachingDecorator = (func) => { + const cache = new Map(); + return function (x) { + if (cache.has(x)) { + return cache.get(x); + } + const res = func(x); + cache.set(x, res); + return res; + }; +}; + +slow = cachingDecorator(slow); + +slow(4).then(slow(5)).then(slow(4)); + +console.log(await slow(5)); +console.log(await slow(4)); From 05b446fc197533bfb150c1f3262eb7df672af91d Mon Sep 17 00:00:00 2001 From: Soham Shah Date: Fri, 27 May 2022 12:18:24 +0530 Subject: [PATCH 06/15] feat: add more snippets in objects, closures and arrays --- Snippets/Arrays/removeDuplicates.js | 16 +++++ Snippets/Closures/armyOfFunctions.js | 23 ++++++ Snippets/Closures/filterThroughFunction.js | 18 +++++ Snippets/Closures/makeCounter.js | 17 +++++ Snippets/Closures/sortByFields.js | 18 +++++ Snippets/Currying/sumOfNNumbers.js | 11 +++ Snippets/DataTypes/methodsOfPrimitives.js | 0 Snippets/Objects/accumulator.js | 13 ++++ Snippets/Objects/calculator.js | 37 ++++++++++ Snippets/Objects/cloneObject.js | 36 ++++++++++ Snippets/Objects/computedProperties.js | 12 ++++ .../immediatelyCalledConstructorFunction.js | 9 +++ Snippets/Objects/isEmpty.js | 11 +++ Snippets/Objects/ladder.js | 19 +++++ Snippets/Objects/methodsAndthis.js | 36 ++++++++++ Snippets/Objects/multiplyNumeric.js | 16 +++++ .../Objects/objectToPrimitiveConversion.js | 0 Snippets/Objects/orderedLikeObject.js | 25 +++++++ Snippets/Objects/reference.js | 17 +++++ Snippets/Objects/restAndspread.js | 71 +++++++++++++++++++ Snippets/Recursion/factorial.js | 8 +++ Snippets/Recursion/fibonacci.js | 26 +++++++ Snippets/Recursion/linkedList.js | 22 ++++++ Snippets/Recursion/power.js | 9 +++ Snippets/Recursion/recursiveTraversal.js | 46 ++++++++++++ Snippets/Recursion/sumTo.js | 10 +++ 26 files changed, 526 insertions(+) create mode 100644 Snippets/Arrays/removeDuplicates.js create mode 100644 Snippets/Closures/armyOfFunctions.js create mode 100644 Snippets/Closures/filterThroughFunction.js create mode 100644 Snippets/Closures/makeCounter.js create mode 100644 Snippets/Closures/sortByFields.js create mode 100644 Snippets/Currying/sumOfNNumbers.js create mode 100644 Snippets/DataTypes/methodsOfPrimitives.js create mode 100644 Snippets/Objects/accumulator.js create mode 100644 Snippets/Objects/calculator.js create mode 100644 Snippets/Objects/cloneObject.js create mode 100644 Snippets/Objects/computedProperties.js create mode 100644 Snippets/Objects/immediatelyCalledConstructorFunction.js create mode 100644 Snippets/Objects/isEmpty.js create mode 100644 Snippets/Objects/ladder.js create mode 100644 Snippets/Objects/methodsAndthis.js create mode 100644 Snippets/Objects/multiplyNumeric.js create mode 100644 Snippets/Objects/objectToPrimitiveConversion.js create mode 100644 Snippets/Objects/orderedLikeObject.js create mode 100644 Snippets/Objects/reference.js create mode 100644 Snippets/Objects/restAndspread.js create mode 100644 Snippets/Recursion/factorial.js create mode 100644 Snippets/Recursion/fibonacci.js create mode 100644 Snippets/Recursion/linkedList.js create mode 100644 Snippets/Recursion/power.js create mode 100644 Snippets/Recursion/recursiveTraversal.js create mode 100644 Snippets/Recursion/sumTo.js diff --git a/Snippets/Arrays/removeDuplicates.js b/Snippets/Arrays/removeDuplicates.js new file mode 100644 index 0000000..a493295 --- /dev/null +++ b/Snippets/Arrays/removeDuplicates.js @@ -0,0 +1,16 @@ +const arr = [1, 2, 2, 3]; + +const updatedArrWithSet = [...new Set(arr)]; + +const updatedArrWithFilter = arr.filter((c, index) => { + return index !== arr.indexOf(c); +}); + +const updatedArrWithIncludes = []; +arr.forEach((c) => { + if (!updatedArrWithIncludes.includes(c)) { + updatedArrWithIncludes.push(c); + } +}); + +console.log(updatedArrWithIncludes); diff --git a/Snippets/Closures/armyOfFunctions.js b/Snippets/Closures/armyOfFunctions.js new file mode 100644 index 0000000..9157e9a --- /dev/null +++ b/Snippets/Closures/armyOfFunctions.js @@ -0,0 +1,23 @@ +function makeArmy() { + let shooters = []; + + let i = 0; + while (i < 10) { + // we can use for loop with let i to avoid the problem + let a = i; // avoid the closure problem of referencing same variable + let shooter = function () { + // create a shooter function, + console.log(a); // that should show its number + }; + shooters.push(shooter); // and add it to the array + i++; + } + + // ...and return the array of shooters + return shooters; +} + +let army = makeArmy(); + +army[1](); +army[9](); diff --git a/Snippets/Closures/filterThroughFunction.js b/Snippets/Closures/filterThroughFunction.js new file mode 100644 index 0000000..00a02c4 --- /dev/null +++ b/Snippets/Closures/filterThroughFunction.js @@ -0,0 +1,18 @@ +const inBetween = (left, right) => { + return function (x) { + return x >= left && x <= right; + }; +}; + +const inArray = (arr) => { + return function (x) { + return arr.includes(x); + }; +}; + +let arr = [1, 2, 3, 4, 5, 6, 7]; + +console.log(arr.filter(inBetween(3, 6))); +// or console.log(arr.filter((item) => inBetween(3, 6)(item))); + +console.log(arr.filter(inArray([1, 2, 10]))); diff --git a/Snippets/Closures/makeCounter.js b/Snippets/Closures/makeCounter.js new file mode 100644 index 0000000..1ae6657 --- /dev/null +++ b/Snippets/Closures/makeCounter.js @@ -0,0 +1,17 @@ +function makeCounter() { + let count = 0; + + return function () { + return ++count; + }; +} + +let counter = makeCounter(); + +counter(); +counter(); +counter(); + +const count = counter(); + +console.log(count); diff --git a/Snippets/Closures/sortByFields.js b/Snippets/Closures/sortByFields.js new file mode 100644 index 0000000..f299a4c --- /dev/null +++ b/Snippets/Closures/sortByFields.js @@ -0,0 +1,18 @@ +let users = [ + { name: "John", age: 20, surname: "Johnson" }, + { name: "Pete", age: 18, surname: "Peterson" }, + { name: "Ann", age: 19, surname: "Hathaway" }, +]; + +// Normal Approach will be +//users.sort((a, b) => (a.name > b.name ? 1 : -1)); +//users.sort((a, b) => (a.age > b.age ? 1 : -1)); + +// cleaner way +const byField = (fieldName) => { + return function (x, y) { + return x[fieldName] > y[fieldName] ? 1 : -1; + }; +}; + +console.log(users.sort(byField("age"))); diff --git a/Snippets/Currying/sumOfNNumbers.js b/Snippets/Currying/sumOfNNumbers.js new file mode 100644 index 0000000..bdf2008 --- /dev/null +++ b/Snippets/Currying/sumOfNNumbers.js @@ -0,0 +1,11 @@ +let sum = function (a) { + return function (b) { + if (b) { + return sum(a + b); + } + return a; + }; +}; + +const total = sum(1)(2)(3)(); +console.log(total); diff --git a/Snippets/DataTypes/methodsOfPrimitives.js b/Snippets/DataTypes/methodsOfPrimitives.js new file mode 100644 index 0000000..e69de29 diff --git a/Snippets/Objects/accumulator.js b/Snippets/Objects/accumulator.js new file mode 100644 index 0000000..5b5098b --- /dev/null +++ b/Snippets/Objects/accumulator.js @@ -0,0 +1,13 @@ +function Accumulator(initValue) { + this.value = initValue; + this.read = (payload) => { + this.value += payload; + }; +} + +let accumulator = new Accumulator(1); // initial value 1 + +accumulator.read(1); +accumulator.read(8); + +console.log(accumulator.value); diff --git a/Snippets/Objects/calculator.js b/Snippets/Objects/calculator.js new file mode 100644 index 0000000..cf560de --- /dev/null +++ b/Snippets/Objects/calculator.js @@ -0,0 +1,37 @@ +class Calculator { + constructor(a, b) { + this.a = a; + this.b = b; + } + + sum() { + console.log(this.a); + console.log(this.a + this.b); + } + + mul() { + console.log(this.a * this.b); + } +} + +const calculator = new Calculator(1, 2); +calculator.sum(); +calculator.mul(); + +// alternate way + +function Calc(a, b) { + this.a = a; + this.b = b; + + this.sum = () => { + return this.a + this.b; + }; + this.mul = () => { + return this.a * this.b; + }; +} + +const calc = new Calc(5, 2); +console.log(calc.sum()); +console.log(calc.mul()); diff --git a/Snippets/Objects/cloneObject.js b/Snippets/Objects/cloneObject.js new file mode 100644 index 0000000..f4c9139 --- /dev/null +++ b/Snippets/Objects/cloneObject.js @@ -0,0 +1,36 @@ +// using copying properties + +let user = { + name: "John", + age: 30, +}; + +let clone = {}; // the new empty object + +// let's copy all user properties into it +for (let key in user) { + clone[key] = user[key]; +} + +// now clone is a fully independent object with the same content +clone.name = "Pete"; // changed the data in it + +console.log(user.name); // still John in the original object + +// Using Object.assign + +let permissions1 = { canView: true }; +let permissions2 = { canEdit: true }; + +// copies all properties from permissions1 and permissions2 into user +Object.assign(user, permissions1, permissions2); + +// now user = { name: "John", canView: true, canEdit: true } + +Object.assign(user, { name: "Pete" }); + +console.log(user.name); // now user = { name: "Pete" } + +let clone2 = Object.assign({}, user); // shallow copy + +console.log(clone2); diff --git a/Snippets/Objects/computedProperties.js b/Snippets/Objects/computedProperties.js new file mode 100644 index 0000000..424e15f --- /dev/null +++ b/Snippets/Objects/computedProperties.js @@ -0,0 +1,12 @@ +const obj = {}; + +for (let i = 0; i < 10; i++) { + obj[`field${i}`] = 1; +} + +console.log(obj); + +let fruit = "apple"; +let bag = { + [fruit + "Computers"]: 5, // bag.appleComputers = 5 +}; diff --git a/Snippets/Objects/immediatelyCalledConstructorFunction.js b/Snippets/Objects/immediatelyCalledConstructorFunction.js new file mode 100644 index 0000000..e974d0e --- /dev/null +++ b/Snippets/Objects/immediatelyCalledConstructorFunction.js @@ -0,0 +1,9 @@ +// create a function and immediately call it with new +let user = new (function () { + this.name = "John"; + this.isAdmin = false; + + // ...other code for user creation + // maybe complex logic and statements + // local variables etc +})(); diff --git a/Snippets/Objects/isEmpty.js b/Snippets/Objects/isEmpty.js new file mode 100644 index 0000000..75fee18 --- /dev/null +++ b/Snippets/Objects/isEmpty.js @@ -0,0 +1,11 @@ +const isEmpty = (obj) => { + return Object.keys(obj).length; +}; + +let schedule = {}; + +console.log(isEmpty(schedule)); // true + +schedule["8:30"] = "get up"; + +console.log(isEmpty(schedule)); // false diff --git a/Snippets/Objects/ladder.js b/Snippets/Objects/ladder.js new file mode 100644 index 0000000..c1482d4 --- /dev/null +++ b/Snippets/Objects/ladder.js @@ -0,0 +1,19 @@ +// chaining + +let ladder = { + step: 0, + up() { + this.step++; + return this; + }, + down() { + this.step--; + return this; + }, + showStep: function () { + // shows the current step + console.log(this.step); + }, +}; + +ladder.up().down(); diff --git a/Snippets/Objects/methodsAndthis.js b/Snippets/Objects/methodsAndthis.js new file mode 100644 index 0000000..bf2b805 --- /dev/null +++ b/Snippets/Objects/methodsAndthis.js @@ -0,0 +1,36 @@ +let user = { + name: "Soham", + age: 5, + sayHi: function () { + console.log("Hi " + this.name); + }, +}; + +let user2 = { + name: "Ashutosh", + age: 15, +}; + +function makeUser() { + return { + name: "John", + ref: this, + }; +} + +let user3 = makeUser(); + +console.log(user3.ref); // undefined in node / Error in browser + +function makeUser2() { + return { + name: "John", + ref() { + return this; + }, + }; +} + +let user4 = makeUser2(); + +console.log(user4.ref().name); // John diff --git a/Snippets/Objects/multiplyNumeric.js b/Snippets/Objects/multiplyNumeric.js new file mode 100644 index 0000000..2fdfb41 --- /dev/null +++ b/Snippets/Objects/multiplyNumeric.js @@ -0,0 +1,16 @@ +const multiplyNumeric = (obj) => { + for (key in obj) { + if (typeof obj[key] === "number") { + obj[key] *= 2; + } + } + console.log(obj); +}; +// before the call +let menu = { + width: 200, + height: 300, + title: "My menu", +}; + +multiplyNumeric(menu); diff --git a/Snippets/Objects/objectToPrimitiveConversion.js b/Snippets/Objects/objectToPrimitiveConversion.js new file mode 100644 index 0000000..e69de29 diff --git a/Snippets/Objects/orderedLikeObject.js b/Snippets/Objects/orderedLikeObject.js new file mode 100644 index 0000000..7ac6166 --- /dev/null +++ b/Snippets/Objects/orderedLikeObject.js @@ -0,0 +1,25 @@ +let codes = { + "+49": "Germany", + "+41": "Switzerland", + "+44": "Great Britain", + // .., + "+1": "USA", +}; + +for (let code in codes) { + console.log(+code); // 49, 41, 44, 1 +} + +codes = { + 49: "Germany", + 41: "Switzerland", + 44: "Great Britain", + // .., + 1: "USA", +}; + +console.log(codes); + +for (let code in codes) { + console.log(code); // 1, 41, 44, 49 +} diff --git a/Snippets/Objects/reference.js b/Snippets/Objects/reference.js new file mode 100644 index 0000000..89ea186 --- /dev/null +++ b/Snippets/Objects/reference.js @@ -0,0 +1,17 @@ +const user = { + name: "Soham", +}; + +const admin = user; + +console.log(admin); + +admin.name = "Dhruvi"; + +console.log(admin); + +user.name = "Samyak"; + +console.log(admin); + +console.log(admin == { name: "Samyak" }); diff --git a/Snippets/Objects/restAndspread.js b/Snippets/Objects/restAndspread.js new file mode 100644 index 0000000..8c8792a --- /dev/null +++ b/Snippets/Objects/restAndspread.js @@ -0,0 +1,71 @@ +// Rest + +function sumAll(...args) { + // args is the name for the array + let sum = 0; + + for (let arg of args) sum += arg; + + return sum; +} + +console.log(sumAll(1, 2, 3)); + +function showName(firstName, lastName, ...titles) { + console.log(firstName + " " + lastName); // Julius Caesar + + // the rest go into titles array + // i.e. titles = ["Consul", "Imperator"] + console.log(titles[0]); // Consul + console.log(titles[1]); // Imperator + console.log(titles.length); // 2 +} + +showName("Julius", "Caesar", "Consul", "Imperator"); + +// arguments array + +function showName2() { + console.log(arguments.length); + console.log(arguments[0]); + console.log(arguments[1]); + + // it's iterable + // for(let arg of arguments) console.log(arg); +} + +// shows: 2, Julius, Caesar +showName2("Julius", "Caesar"); + +// shows: 1, Ilya, undefined (no second argument) +showName2("Ilya"); + +// BEWARE: Arrow Functions dont have "arguments" + +function f() { + // If we access the arguments object from an arrow function, it takes them from the outer “normal” function. + + let showArg = () => console.log(arguments[0]); + showArg(); +} + +f(1); // 1 + +// Spread + +let arr1 = [1, -2, 3, 4]; +let arr2 = [8, 3, -8, 1]; + +console.log(Math.max(...arr1, ...arr2)); // 8 + +let str = "Hello"; + +// Array.from converts an iterable and array-like object into an array +console.log(Array.from(str)); // H,e,l,l,o + +// Array-like is an object that index and length property + +let arrLike = { 0: "foo", 5: "bar", length: 6 }; +console.log(Array.from(arrLike)); + +console.log(Array.from([1, 2, 3], (x) => x + x)); diff --git a/Snippets/Recursion/factorial.js b/Snippets/Recursion/factorial.js new file mode 100644 index 0000000..2bca7aa --- /dev/null +++ b/Snippets/Recursion/factorial.js @@ -0,0 +1,8 @@ +const factorial = (num) => { + if (num === 1) { + return 1; + } + return num * factorial(num - 1); +}; + +console.log(factorial(5)); diff --git a/Snippets/Recursion/fibonacci.js b/Snippets/Recursion/fibonacci.js new file mode 100644 index 0000000..bc17d9f --- /dev/null +++ b/Snippets/Recursion/fibonacci.js @@ -0,0 +1,26 @@ +// fibonacci + +const fibonacci = (num) => { + if (num === 1) { + return 1; + } + if (num === 0) { + return 0; + } + return fibonacci(num - 2) + fibonacci(num - 1); +}; + +console.log(fibonacci(7)); + +// DP Approach + +function fib(n) { + let a = 1; + let b = 1; + for (let i = 3; i <= n; i++) { + let c = a + b; + a = b; + b = c; + } + return b; +} diff --git a/Snippets/Recursion/linkedList.js b/Snippets/Recursion/linkedList.js new file mode 100644 index 0000000..eb13922 --- /dev/null +++ b/Snippets/Recursion/linkedList.js @@ -0,0 +1,22 @@ +let list = { + value: 1, + next: { + value: 2, + next: { + value: 3, + next: { + value: 4, + next: null, + }, + }, + }, +}; + +const printList = (obj) => { + console.log(obj.value); + if (obj.next !== null) { + printList(obj.next); + } +}; + +console.log(printList(list)); diff --git a/Snippets/Recursion/power.js b/Snippets/Recursion/power.js new file mode 100644 index 0000000..967bacf --- /dev/null +++ b/Snippets/Recursion/power.js @@ -0,0 +1,9 @@ +const power = (x, n) => { + console.log(x, n); + if (n === 1) { + return x; + } + return x * power(x, n - 1); +}; + +console.log(power(2, 3)); diff --git a/Snippets/Recursion/recursiveTraversal.js b/Snippets/Recursion/recursiveTraversal.js new file mode 100644 index 0000000..f85bc4a --- /dev/null +++ b/Snippets/Recursion/recursiveTraversal.js @@ -0,0 +1,46 @@ +let company = { + sales: [ + { + name: "John", + salary: 1000, + }, + { + name: "Alice", + salary: 1600, + }, + ], + + development: { + sites: [ + { + name: "Peter", + salary: 2000, + }, + { + name: "Alex", + salary: 1800, + }, + ], + + internals: [ + { + name: "Jack", + salary: 1300, + }, + ], + }, +}; + +const computeSalary = (department, salary) => { + if (Array.isArray(department)) { + return department.reduce((prev, current) => prev + current.salary, 0); + } else { + let sum = 0; + for (let subDep of Object.values(department)) { + sum += computeSalary(subDep); + } + return sum; + } +}; + +console.log(computeSalary(company)); diff --git a/Snippets/Recursion/sumTo.js b/Snippets/Recursion/sumTo.js new file mode 100644 index 0000000..0ab4e8e --- /dev/null +++ b/Snippets/Recursion/sumTo.js @@ -0,0 +1,10 @@ +const sumTo = (n) => { + if (n === 1) { + return 1; + } else { + return n + sumTo(n - 1); + } +}; + +console.log(sumTo(5)); // 15 +console.log(sumTo(100000)); // error From 6aa3bbec1b6a751ec676c1a02a7e93a6598b73eb Mon Sep 17 00:00:00 2001 From: Soham Shah Date: Fri, 27 May 2022 15:53:02 +0530 Subject: [PATCH 07/15] feat: add functions code --- Snippets/Functions/bind.js | 21 +++++++++++++++++++ Snippets/Functions/bindAll.js | 19 +++++++++++++++++ Snippets/Functions/boundFunctionMethod.js | 11 ++++++++++ Snippets/Functions/fixFunctionThis.js | 19 +++++++++++++++++ Snippets/Functions/globalPartialFunctions.js | 22 ++++++++++++++++++++ Snippets/Functions/partialFunctions.js | 22 ++++++++++++++++++++ Snippets/Functions/partialLogin.js | 15 +++++++++++++ Snippets/Functions/secondBind.js | 10 +++++++++ 8 files changed, 139 insertions(+) create mode 100644 Snippets/Functions/bind.js create mode 100644 Snippets/Functions/bindAll.js create mode 100644 Snippets/Functions/boundFunctionMethod.js create mode 100644 Snippets/Functions/fixFunctionThis.js create mode 100644 Snippets/Functions/globalPartialFunctions.js create mode 100644 Snippets/Functions/partialFunctions.js create mode 100644 Snippets/Functions/partialLogin.js create mode 100644 Snippets/Functions/secondBind.js diff --git a/Snippets/Functions/bind.js b/Snippets/Functions/bind.js new file mode 100644 index 0000000..001aa36 --- /dev/null +++ b/Snippets/Functions/bind.js @@ -0,0 +1,21 @@ +let user = { + firstName: "John", + sayHi() { + alert(`Hello, ${this.firstName}!`); + }, +}; + +let sayHi = user.sayHi.bind(user); // (*) + +// can run it without an object +sayHi(); // Hello, John! + +setTimeout(sayHi, 1000); // Hello, John! + +// even if the value of user changes within 1 second +// sayHi uses the pre-bound value which is reference to the old user object +user = { + sayHi() { + alert("Another user in setTimeout!"); + }, +}; diff --git a/Snippets/Functions/bindAll.js b/Snippets/Functions/bindAll.js new file mode 100644 index 0000000..8d1acf2 --- /dev/null +++ b/Snippets/Functions/bindAll.js @@ -0,0 +1,19 @@ +// If an object has many methods and we plan to actively pass it around, then we could bind them all in a loop + +const user = { + func1() { + console.log("func 1"); + }, + func2() { + console.log("func 2"); + }, + func3() { + console.log("func 3"); + }, +}; + +for (let key in user) { + if (typeof user[key] == "function") { + user[key] = user[key].bind(user); + } +} diff --git a/Snippets/Functions/boundFunctionMethod.js b/Snippets/Functions/boundFunctionMethod.js new file mode 100644 index 0000000..4e2d792 --- /dev/null +++ b/Snippets/Functions/boundFunctionMethod.js @@ -0,0 +1,11 @@ +"use strict"; +function f() { + console.log(this); // null +} + +let user = { + g: f.bind(null), +}; + +// f(); +user.g(); diff --git a/Snippets/Functions/fixFunctionThis.js b/Snippets/Functions/fixFunctionThis.js new file mode 100644 index 0000000..76d4eed --- /dev/null +++ b/Snippets/Functions/fixFunctionThis.js @@ -0,0 +1,19 @@ +function askPassword(ok, fail) { + let password = "rockstar"; + if (password == "rockstar") ok(); + else fail(); +} + +let user = { + name: "John", + + loginOk() { + console.log(`${this.name} logged in`); + }, + + loginFail() { + console.log(`${this.name} failed to log in`); + }, +}; + +askPassword(user.loginOk.bind(user), user.loginFail.bind(user)); diff --git a/Snippets/Functions/globalPartialFunctions.js b/Snippets/Functions/globalPartialFunctions.js new file mode 100644 index 0000000..7df8409 --- /dev/null +++ b/Snippets/Functions/globalPartialFunctions.js @@ -0,0 +1,22 @@ +function partial(func, ...argsBound) { + return function (...args) { + // (*) + return func.call(this, ...argsBound, ...args); + }; +} + +// Usage: +let user = { + firstName: "John", + say(time, phrase) { + alert(`[${time}] ${this.firstName}: ${phrase}!`); + }, +}; + +// add a partial method with fixed time +user.sayNow = partial( + user.say, + new Date().getHours() + ":" + new Date().getMinutes() +); + +user.sayNow("Hello"); diff --git a/Snippets/Functions/partialFunctions.js b/Snippets/Functions/partialFunctions.js new file mode 100644 index 0000000..fd674d6 --- /dev/null +++ b/Snippets/Functions/partialFunctions.js @@ -0,0 +1,22 @@ +function mul(a, b) { + return a * b; +} + +const triple = mul.bind(null, 3); // alternative to this is to curry functions + +console.log(triple(4)); + +const user = { + firstName: "Samyak Shah", +}; +function send(from, text, to) { + return ` + By: ${from} + To: ${to} + Message: + ${text}, ${this.firstName}`; +} + +const sendTo = send.bind(user, "soham@invact.com"); + +console.log(sendTo("Hello World", "samyak@neog.com")); diff --git a/Snippets/Functions/partialLogin.js b/Snippets/Functions/partialLogin.js new file mode 100644 index 0000000..216436d --- /dev/null +++ b/Snippets/Functions/partialLogin.js @@ -0,0 +1,15 @@ +function askPassword(ok, fail) { + let password = prompt("Password?", ""); + if (password == "rockstar") ok(); + else fail(); +} + +let user = { + name: "John", + + login(result) { + alert(this.name + (result ? " logged in" : " failed to log in")); + }, +}; + +askPassword(user.login.bind(user, true), user.login.bind(user, false)); // ? diff --git a/Snippets/Functions/secondBind.js b/Snippets/Functions/secondBind.js new file mode 100644 index 0000000..4684187 --- /dev/null +++ b/Snippets/Functions/secondBind.js @@ -0,0 +1,10 @@ +// A function cannot be re-bound +function f() { + console.log(this.name); +} + +f = f.bind({ name: "John" }); +z = f.bind({ name: "Ann" }); + +f(); // John +z(); // John From c876bb064dd17d3809485ee3a829274926a1d503 Mon Sep 17 00:00:00 2001 From: Soham Shah Date: Sat, 28 May 2022 00:55:25 +0530 Subject: [PATCH 08/15] feat: add promise pollyfils --- Snippets/Promises/promiseAll.js | 33 ++++++++++++++++++ Snippets/Promises/promiseAllSettled.js | 33 ++++++++++++++++++ Snippets/Promises/promiseAny.js | 46 ++++++++++++++++++++++++++ Snippets/Promises/promiseRace.js | 24 ++++++++++++++ 4 files changed, 136 insertions(+) create mode 100644 Snippets/Promises/promiseAll.js create mode 100644 Snippets/Promises/promiseAllSettled.js create mode 100644 Snippets/Promises/promiseAny.js create mode 100644 Snippets/Promises/promiseRace.js diff --git a/Snippets/Promises/promiseAll.js b/Snippets/Promises/promiseAll.js new file mode 100644 index 0000000..651e672 --- /dev/null +++ b/Snippets/Promises/promiseAll.js @@ -0,0 +1,33 @@ +Promise.myAll = function (promises) { + return new Promise((resolve, reject) => { + let results = []; + let count = 0; + let toBeRejected = false; + + promises.forEach((promise, index) => { + if (toBeRejected) return; + Promise.resolve(promise) + .then((res) => { + count += 1; + results[index] = res; // maintaining the order + if (count === promises.length) { + resolve(results); + } + }) + .catch((err) => { + reject(err); + toBeRejected = true; + }); + }); + }); +}; + +const promise1 = Promise.resolve(1); +const promise2 = new Promise((resolve, reject) => + setTimeout(() => resolve(2), 3000) +); +const promise3 = 3; + +Promise.myAll([Promise.reject("bar"), promise1, promise2, promise3]) + .then((value) => console.log(value)) + .catch((err) => console.log(err)); diff --git a/Snippets/Promises/promiseAllSettled.js b/Snippets/Promises/promiseAllSettled.js new file mode 100644 index 0000000..bdbf1f8 --- /dev/null +++ b/Snippets/Promises/promiseAllSettled.js @@ -0,0 +1,33 @@ +Promise.myAllSettled = function (promises) { + let results = []; + let count = 0; + return new Promise((resolve, reject) => { + promises.forEach((promise, index) => { + Promise.resolve(promise) + .then((value) => { + count += 1; + results[index] = value; + if (count === promises.length) { + resolve(results); + } + }) + .catch((err) => { + count += 1; + results[index] = "Error: " + err; + if (count === promises.length) { + resolve(results); + } + }); + }); + }); +}; + +const promise1 = Promise.resolve(1); +const promise2 = new Promise((resolve, reject) => + setTimeout(() => resolve(2), 3000) +); +const promise3 = 3; + +Promise.myAllSettled([Promise.reject("bar"), promise1, promise2, promise3]) + .then((value) => console.log(value)) + .catch((err) => console.log(err)); diff --git a/Snippets/Promises/promiseAny.js b/Snippets/Promises/promiseAny.js new file mode 100644 index 0000000..b163a07 --- /dev/null +++ b/Snippets/Promises/promiseAny.js @@ -0,0 +1,46 @@ +Promise.myAny = function (promises) { + let errList = []; + let errCount = 0; + return new Promise((resolve, reject) => { + promises.forEach((promise, index) => { + Promise.resolve(promise).then( + (value) => { + return resolve(value); + }, + (reason) => { + errList[index] = reason; + errCount += 1; + if (errCount === promises.length) { + return reject([ + new AggregateError([errList], "All promises were rejected"), + ]); + } + } + ); + }); + }); +}; + +const promise1 = Promise.resolve(1); +const promise2 = new Promise((resolve, reject) => + setTimeout(() => resolve(2), 3000) +); +const promise3 = Promise.resolve(3); + +Promise.myAny([ + Promise.reject("bar"), + Promise.reject("foo"), + Promise.reject("nice"), + Promise.reject("wow"), +]) + .then((value) => console.log(value)) + .catch((err) => console.log(err)); + +Promise.any([ + Promise.reject("bar"), + Promise.reject("foo"), + Promise.reject("nice"), + Promise.reject("wow"), +]) + .then((value) => console.log(value)) + .catch((err) => console.log(err)); diff --git a/Snippets/Promises/promiseRace.js b/Snippets/Promises/promiseRace.js new file mode 100644 index 0000000..94fb770 --- /dev/null +++ b/Snippets/Promises/promiseRace.js @@ -0,0 +1,24 @@ +Promise.myRace = function (promises) { + return new Promise((resolve, reject) => { + promises.forEach((promise) => { + Promise.resolve(promise).then( + (value) => resolve(value), + (reason) => reject(reason) + ); + }); + }); +}; + +const promise1 = Promise.resolve(1); +const promise2 = new Promise((resolve, reject) => + setTimeout(() => resolve(2), 3000) +); +const promise3 = Promise.resolve(3); + +Promise.myRace([Promise.reject(new Error("bar")), promise1, promise2, promise3]) + .then((value) => console.log(value)) + .catch((err) => console.log("error")); + +Promise.race([Promise.reject("bar"), promise1, promise2, promise3]) + .then((value) => console.log(value)) + .catch((err) => console.log("error")); From b3aa8c2aeb2867561dba21efebcaa3ce82e45007 Mon Sep 17 00:00:00 2001 From: Soham Shah Date: Sat, 28 May 2022 00:56:11 +0530 Subject: [PATCH 09/15] feat: add object and functions snippets --- Snippets/Functions/fixFunctionThis.js | 2 ++ Snippets/Objects/cloneObject.js | 4 +++ Snippets/Objects/propertyDescriptors.js | 30 +++++++++++++++++++++++ Snippets/Objects/propertyGetterSetter.js | 31 ++++++++++++++++++++++++ 4 files changed, 67 insertions(+) create mode 100644 Snippets/Objects/propertyDescriptors.js create mode 100644 Snippets/Objects/propertyGetterSetter.js diff --git a/Snippets/Functions/fixFunctionThis.js b/Snippets/Functions/fixFunctionThis.js index 76d4eed..4c12b1e 100644 --- a/Snippets/Functions/fixFunctionThis.js +++ b/Snippets/Functions/fixFunctionThis.js @@ -17,3 +17,5 @@ let user = { }; askPassword(user.loginOk.bind(user), user.loginFail.bind(user)); + +// askPassword(() => user.loginOk(), () => user.loginFail()); diff --git a/Snippets/Objects/cloneObject.js b/Snippets/Objects/cloneObject.js index f4c9139..093088c 100644 --- a/Snippets/Objects/cloneObject.js +++ b/Snippets/Objects/cloneObject.js @@ -34,3 +34,7 @@ console.log(user.name); // now user = { name: "Pete" } let clone2 = Object.assign({}, user); // shallow copy console.log(clone2); + +// clone in a different way + +let clone = Object.defineProperties({}, Object.getOwnPropertyDescriptors(obj)); diff --git a/Snippets/Objects/propertyDescriptors.js b/Snippets/Objects/propertyDescriptors.js new file mode 100644 index 0000000..d84689a --- /dev/null +++ b/Snippets/Objects/propertyDescriptors.js @@ -0,0 +1,30 @@ +let user = { + name: "John", +}; + +// get property +let descriptor = Object.getOwnPropertyDescriptor(user, "name"); + +console.log(descriptor); + +// define property +Object.defineProperty(user, "name", { + value: "Soham", +}); + +// non-writable +Object.defineProperty(user, "name", { + writable: false, +}); + +// non-enumerable + +Object.defineProperty(user, "toString", { + enumerable: false, +}); + +// non-configurable + +Object.defineProperty(user, "name", { configurable: false }); + +// cannot even change other ennumberable and writable diff --git a/Snippets/Objects/propertyGetterSetter.js b/Snippets/Objects/propertyGetterSetter.js new file mode 100644 index 0000000..9bd6a80 --- /dev/null +++ b/Snippets/Objects/propertyGetterSetter.js @@ -0,0 +1,31 @@ +let obj = { + name: "Soham", + surname: "Shah", + get fullName() { + return `${this.name} ${this.surname}`; + }, + set propName(value) { + [this.name, this.surname] = value.split(" "); + }, +}; + +// hiding a variable + +let user = { + get name() { + return this._name; + }, + + set name(value) { + if (value.length < 4) { + alert("Name is too short, need at least 4 characters"); + return; + } + this._name = value; + }, +}; + +user.name = "Pete"; +alert(user.name); // Pete + +user.name = ""; From aca9daac787d4f1110c7920213820ba8dea9c521 Mon Sep 17 00:00:00 2001 From: Soham Shah Date: Sun, 29 May 2022 01:46:08 +0530 Subject: [PATCH 10/15] feat: add array questions --- Snippets/Arrays/flattenADeeplyNestedArray.js | 27 ++++ Snippets/Arrays/groupBy.js | 125 +++++++++++++++++++ 2 files changed, 152 insertions(+) create mode 100644 Snippets/Arrays/flattenADeeplyNestedArray.js create mode 100644 Snippets/Arrays/groupBy.js diff --git a/Snippets/Arrays/flattenADeeplyNestedArray.js b/Snippets/Arrays/flattenADeeplyNestedArray.js new file mode 100644 index 0000000..379f66c --- /dev/null +++ b/Snippets/Arrays/flattenADeeplyNestedArray.js @@ -0,0 +1,27 @@ +function flattenArray(arr, n = Infinity) { + let res = []; + for (i in arr) { + if (n !== 0 && Array.isArray(arr[i])) { + res.push(...flattenArray(arr[i], n - 1)); + } else { + res.push(arr[i]); + } + } + return res; +} +let input = [ + 1, + 2, + 3, + [4], + [5, 6, [7], [8, [9, [10]]]], + 11, + 12, + 13, + [14, [[[[[15, [16]]]]]]], + 17, + 18, + [19, [20, [21, [22, [23, [24, [[[[[25]]]]]]]]]]], +]; + +console.log(flattenArray(input, 2)); diff --git a/Snippets/Arrays/groupBy.js b/Snippets/Arrays/groupBy.js new file mode 100644 index 0000000..d4d0731 --- /dev/null +++ b/Snippets/Arrays/groupBy.js @@ -0,0 +1,125 @@ +const arr = [6.1, 2.4, 2.7, 6.8]; + +function groupBy(arr, property) { + const groupByString = (arr, query) => { + let res = {}; + + arr.forEach((item, index) => { + const queryList = query.split("."); + + let currKey; + let currItem = item; + let count = 0; + for (let i = 0; i < queryList.length; i++) { + currKey = queryList[i]; + if (!currItem[currKey]) { + break; + } else { + count += 1; + currItem = currItem[currKey]; + } + } + + if (count !== queryList.length) { + currItem = undefined; + } + if (!res[currItem]) { + res[currItem] = [item]; + } else { + res[currItem].push(item); + } + }); + return res; + }; + const groupByCallback = (arr, cb) => { + let res = {}; + arr.forEach((item) => { + const ans = cb.call(null, item); + + if (Object.keys(res).includes(ans.toString())) { + res[ans].push(item); + } else { + res[ans] = [item]; + } + }); + return res; + }; + + let res; + switch (typeof property) { + case "function": + res = groupByCallback(arr, property); + break; + case "string": + res = groupByString(arr, property); + break; + default: + return new Error("Invalid Property Type"); + } + + return res; +} + +// groupBy(arr, Math.floor); +console.log(groupBy(arr, Math.ceil)); +console.log(groupBy([6.1, 4.2, 6.3], Math.floor)); +console.log(groupBy(["one", "two", "three"], "length")); +console.log( + groupBy( + [{ a: { b: { c: 1 } } }, { a: { b: { c: 1 } } }, { a: { b: { c: 2 } } }], + "b.a.c" + ) +); + +console.log( + groupBy( + [{ a: { b: { c: 1 } } }, { a: { b: { c: 1 } } }, { a: { b: { c: 2 } } }], + "a.b.c" + ) +); + +// alternate solution +function groupByAlternative(collection, property) { + const output = {}; + + if (!collection || typeof collection !== "object") { + return output; + } + + const isPropertyFunction = typeof property === "function"; + const isPropertyPath = typeof property === "string"; + + for (const value of Object.values(collection)) { + let current = undefined; + + if (isPropertyFunction) { + current = property(value); + } else if (isPropertyPath) { + // a.b.c -> [a, b, c]; + const path = property.split("."); + let i; + let currentKey; + let currentItem = value; // { a: { b: { c: 1 } } } + + for (i = 0; i < path.length; i++) { + // [a, b, c] -> currentKey: path[0] -> a + // [a, b, c] -> currentKey: path[1] -> b + // [a, b, c] -> currentKey: path[2] -> c + currentKey = path[i]; + + if (!currentItem[currentKey]) { + currentItem = undefined; + break; + } + currentItem = currentItem[currentKey]; + } + + current = currentItem; + } + + output[current] = output[current] || []; + output[current].push(value); + } + + return output; +} From 8218d90f7cdc4b719c5dbb1f8fac0e89dec82eca Mon Sep 17 00:00:00 2001 From: Soham Shah Date: Mon, 30 May 2022 10:25:20 +0530 Subject: [PATCH 11/15] feat: add calculator chaining code --- Snippets/Objects/calculator.js | 53 ++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/Snippets/Objects/calculator.js b/Snippets/Objects/calculator.js index cf560de..fc4fb44 100644 --- a/Snippets/Objects/calculator.js +++ b/Snippets/Objects/calculator.js @@ -7,10 +7,12 @@ class Calculator { sum() { console.log(this.a); console.log(this.a + this.b); + return this; } mul() { console.log(this.a * this.b); + return this; } } @@ -35,3 +37,54 @@ function Calc(a, b) { const calc = new Calc(5, 2); console.log(calc.sum()); console.log(calc.mul()); + +// approach 2: with chaining + +function Calculator(initialValue) { + this.total = initialValue; + this.sum = function (a) { + this.total += a; + return this; + }; + this.sub = function (a) { + this.total -= a; + return this; + }; + this.misc = function (cb) { + this.total = cb(this.total); + return this; + }; + this.val = function () { + return this.total; + }; +} + +const cal = new Calculator(2); +console.print( + cal + .sum(2) + .misc((val) => val + 100) + .val() +); + +// approach 3: using functions + +function cal(initialValue) { + let total = initialValue; + + function add(a) { + total += a; + return cal(total); + } + + function val() { + return total; + } + + return { + add, + val, + }; +} + +console.print(cal(2).add(2).add(2).val()); From 3229ec45139a9da1c8fbe3d3cb809d61e8b69c07 Mon Sep 17 00:00:00 2001 From: Soham Shah Date: Mon, 30 May 2022 11:41:43 +0530 Subject: [PATCH 12/15] feat: add memoize one --- Snippets/Functions/memoizeOne.js | 38 ++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 Snippets/Functions/memoizeOne.js diff --git a/Snippets/Functions/memoizeOne.js b/Snippets/Functions/memoizeOne.js new file mode 100644 index 0000000..db4db13 --- /dev/null +++ b/Snippets/Functions/memoizeOne.js @@ -0,0 +1,38 @@ +/** + * Do not change the function name + **/ + +function memoizeOne(fn, isEqual) { + let cache = {}; + + function hasher(args) { + return args.join(","); + } + return function (...args) { + const hash = hasher(args); + if (cache[hash]) { + return cache[hash]; + } + cache = {}; + const res = fn.apply(null, args); + cache[hash] = res; + return res; + }; +} + +function add(a, b) { + console.print("called"); + return a + b; +} + +function isEqual(a, b) { + if (a === b) { + return true; + } + return false; +} +const memoizeAdd = memoizeOne(add, isEqual); +console.print(memoizeAdd(2, 3)); +console.print(memoizeAdd(2, 3)); +console.print(memoizeAdd(3, 4)); +console.print(memoizeAdd(5, 6)); From 288c342a051c5e60ee1a00f926e8c5278d95f09a Mon Sep 17 00:00:00 2001 From: Soham Shah Date: Wed, 15 Jun 2022 20:36:39 +0530 Subject: [PATCH 13/15] add more solutions snippets --- Snippets/Arrays/arraySubset.js | 25 ++++++++++++++ Snippets/Arrays/atPolyfill.js | 10 ++++++ Snippets/Arrays/filterPolyfill.js | 14 ++++++++ Snippets/Arrays/mapPolyfill.js | 12 +++++++ Snippets/Arrays/pushPolyfill.js | 9 +++++ Snippets/Arrays/reducePolyfill.js | 17 ++++++++++ Snippets/Arrays/unshiftPolyfill.js | 19 +++++++++++ .../Currying/advancedCurryImplementation.js | 33 +++++++++++++++++++ Snippets/Functions/timeBomb.js | 10 ++++++ Snippets/Objects/bindPolyFill.js | 18 ++++++++++ Snippets/Objects/deepCopy.js | 20 +++++++++++ 11 files changed, 187 insertions(+) create mode 100644 Snippets/Arrays/arraySubset.js create mode 100644 Snippets/Arrays/atPolyfill.js create mode 100644 Snippets/Arrays/filterPolyfill.js create mode 100644 Snippets/Arrays/mapPolyfill.js create mode 100644 Snippets/Arrays/pushPolyfill.js create mode 100644 Snippets/Arrays/reducePolyfill.js create mode 100644 Snippets/Arrays/unshiftPolyfill.js create mode 100644 Snippets/Currying/advancedCurryImplementation.js create mode 100644 Snippets/Functions/timeBomb.js create mode 100644 Snippets/Objects/bindPolyFill.js create mode 100644 Snippets/Objects/deepCopy.js diff --git a/Snippets/Arrays/arraySubset.js b/Snippets/Arrays/arraySubset.js new file mode 100644 index 0000000..5523e39 --- /dev/null +++ b/Snippets/Arrays/arraySubset.js @@ -0,0 +1,25 @@ +const arr1 = [2, 3, 4, 5, 6, 88, 9]; +const arr2 = [3, 3, 3, 5, 100]; + +function isSubset(arr1, arr2) { + const arr1Set = []; + const arr2Set = []; + + arr1.forEach((item) => { + if (!arr1Set.includes(item)) { + arr1Set.push(item); + } + }); + arr2.forEach((item) => { + if (!arr2Set.includes(item)) { + arr2Set.push(item); + } + }); + + const res = arr1Set.reduce((previousValue, currentValue) => { + return previousValue + +arr2Set.includes(currentValue); + }, 0); + return res === arr2Set.length; +} + +console.log(isSubset(arr1, arr2)); diff --git a/Snippets/Arrays/atPolyfill.js b/Snippets/Arrays/atPolyfill.js new file mode 100644 index 0000000..3853401 --- /dev/null +++ b/Snippets/Arrays/atPolyfill.js @@ -0,0 +1,10 @@ +Array.prototype.myAt = myAt; + +function myAt(index) { + if (index >= 0) { + return this[index]; + } + return this[this.length - -index]; +} + +console.log([1, 2, 3].myAt(-4)); diff --git a/Snippets/Arrays/filterPolyfill.js b/Snippets/Arrays/filterPolyfill.js new file mode 100644 index 0000000..d70c249 --- /dev/null +++ b/Snippets/Arrays/filterPolyfill.js @@ -0,0 +1,14 @@ +Array.prototype.myFilter = myFilter; + +function myFilter(cb) { + const filteredArr = []; + this.forEach((item) => { + if (cb(item)) { + filteredArr.push(item); + } + }); + return filteredArr; +} + +const arr = [1, 2, 3, 4]; +console.log(arr.myFilter((item) => item !== 2)); diff --git a/Snippets/Arrays/mapPolyfill.js b/Snippets/Arrays/mapPolyfill.js new file mode 100644 index 0000000..4caf00c --- /dev/null +++ b/Snippets/Arrays/mapPolyfill.js @@ -0,0 +1,12 @@ +Array.prototype.myMap = myMap; + +function myMap(cb) { + const newArr = []; + for (let i = 0; i < this.length; i++) { + newArr.push(cb(this[i])); + } + return newArr; +} +const arr = [1, 2, 3, 4, 5]; + +console.log(arr.myMap((item) => item + 2)); diff --git a/Snippets/Arrays/pushPolyfill.js b/Snippets/Arrays/pushPolyfill.js new file mode 100644 index 0000000..ce9c9e2 --- /dev/null +++ b/Snippets/Arrays/pushPolyfill.js @@ -0,0 +1,9 @@ +Array.prototype.myPush = myPush; + +function myPush(item) { + this[this.length] = item; + return this; +} +const arr = [1, 2, 3]; +arr.myPush(2).push(2); // chaining possible +console.log(arr); diff --git a/Snippets/Arrays/reducePolyfill.js b/Snippets/Arrays/reducePolyfill.js new file mode 100644 index 0000000..ede890b --- /dev/null +++ b/Snippets/Arrays/reducePolyfill.js @@ -0,0 +1,17 @@ +Array.prototype.myReduce = myReduce; + +function myReduce(cb, initialValue = this[0]) { + let result = initialValue; + this.forEach((item) => { + result = cb(result, item); + }); + return result; +} + +const array1 = [1, 2, 3, 4]; +const sumWithInitial = array1.myReduce( + (previousValue, currentValue) => previousValue + currentValue, + 0 +); + +console.log(sumWithInitial); diff --git a/Snippets/Arrays/unshiftPolyfill.js b/Snippets/Arrays/unshiftPolyfill.js new file mode 100644 index 0000000..dfa1f65 --- /dev/null +++ b/Snippets/Arrays/unshiftPolyfill.js @@ -0,0 +1,19 @@ +Array.prototype.myUnshift = myUnshift; + +function myUnshift(item) { + let prevItem = item; + const originalLength = this.length; + for (let i = 0; i <= originalLength; i++) { + let temp = this[i]; + this[i] = prevItem; + prevItem = temp; + } + return this; +} + +const arr = [1, 2, 3, 4]; +arr + .myUnshift(2) + .myUnshift(100) + .myUnshift(() => console.log("WOW")); +console.log(arr); diff --git a/Snippets/Currying/advancedCurryImplementation.js b/Snippets/Currying/advancedCurryImplementation.js new file mode 100644 index 0000000..a8debcf --- /dev/null +++ b/Snippets/Currying/advancedCurryImplementation.js @@ -0,0 +1,33 @@ +function sum(a, b, c) { + return a + b + c; +} + +// function curry(fn) { +// return function curried(...args) { +// if (args.length >= fn.length) { +// return fn.apply(this, args); +// } else { +// return function (...args2) { +// return curried.apply(this, args.concat(args2)); +// }; +// } +// }; +// } + +function curry(func) { + return function curried(...args) { + if (args.length >= func.length) { + return func.apply(this, args); + } else { + return function (...args2) { + return curried.apply(this, args.concat(args2)); + }; + } + }; +} + +let curriedSum = curry(sum); + +console.log(curriedSum(1, 2, 3)); // 6, still callable normally +console.log(curriedSum(1)(2, 3)); // 6, currying of 1st arg +console.log(curriedSum(1)(2)(3)); diff --git a/Snippets/Functions/timeBomb.js b/Snippets/Functions/timeBomb.js new file mode 100644 index 0000000..f72451a --- /dev/null +++ b/Snippets/Functions/timeBomb.js @@ -0,0 +1,10 @@ +// 5,4,3,2,1, Bang! + +function timeBomb(i) { + return i === 0 ? "Bang" : i; +} +for (let i = 5; i >= 0; i--) { + setTimeout(() => { + console.log(timeBomb(i)); + }, [(5 - i) * 1000]); +} diff --git a/Snippets/Objects/bindPolyFill.js b/Snippets/Objects/bindPolyFill.js new file mode 100644 index 0000000..633ecd0 --- /dev/null +++ b/Snippets/Objects/bindPolyFill.js @@ -0,0 +1,18 @@ +Function.prototype.myBind = myBind; + +function myBind(context, ...args1) { + const newContext = this; + return function (...args2) { + newContext.apply(context, [...args1, ...args2]); + }; +} + +let user = { + firstName: "John", + sayHi(area, birthdate) { + console.log(`Hello, ${this.firstName} from ${area}, born on ${birthdate}!`); + }, +}; + +let sayHi = user.sayHi.myBind(user, "Ahmedabad"); // (*) +sayHi("26/06"); diff --git a/Snippets/Objects/deepCopy.js b/Snippets/Objects/deepCopy.js new file mode 100644 index 0000000..e335bce --- /dev/null +++ b/Snippets/Objects/deepCopy.js @@ -0,0 +1,20 @@ +const x = { b: [{ a: [1, 2, 3], b: [4, 5, 6], c: [7, 8, 9] }] }; +const y = { b: [{ a: [1, 2, 3], b: [4, 5, 6], c: [7, 8, 9] }] }; + +const z = deepCopy(x); + +function deepCopy(obj) { + let target = {}; + const keys = Object.keys(obj); + keys.forEach((key) => { + if (typeof obj[key] === "object") { + target[key] = deepCopy(obj[key]); + } else { + target[key] = obj[key]; + } + }); + return target; +} + +console.log(z); +console.log(z === x); From 8af48465775464b3637ecc8ae35b7a1e09722b73 Mon Sep 17 00:00:00 2001 From: sohamsshah Date: Sat, 28 Oct 2023 13:12:06 +0530 Subject: [PATCH 14/15] docs: add a comment in BubbleSort.js --- DSA/Arrays/BubbleSort.js | 1 + 1 file changed, 1 insertion(+) diff --git a/DSA/Arrays/BubbleSort.js b/DSA/Arrays/BubbleSort.js index c37a9d6..2781e9c 100644 --- a/DSA/Arrays/BubbleSort.js +++ b/DSA/Arrays/BubbleSort.js @@ -9,6 +9,7 @@ if(arr[j] > arr[j+1]){ + // creates a temp array var temp = arr[j] arr[j] = arr[j + 1] arr[j+1] = temp From 60bc7ce084bbeeb96dd78be86bcfbc11ff8942df Mon Sep 17 00:00:00 2001 From: sohamsshah Date: Sat, 28 Oct 2023 13:14:39 +0530 Subject: [PATCH 15/15] docs: more changes --- DSA/Arrays/BucketSort.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DSA/Arrays/BucketSort.js b/DSA/Arrays/BucketSort.js index 52ad644..1dd93a9 100644 --- a/DSA/Arrays/BucketSort.js +++ b/DSA/Arrays/BucketSort.js @@ -1,4 +1,6 @@ const arr = [5, 3, 1, 2, 4, 7, 6]; + +// bucket sort algo const bucketSort = (arr) => { if (arr.length === 0) { return arr;