├── 1. Callbacks and Higher-Order Functions ├── index.html └── index.js ├── 2. Closure, Scope and ExecutionContext ├── index.html └── index.js ├── 3. Async ├── index.html └── index.js ├── 4. OOP ├── index.html └── index.js ├── 5. Promises ├── index.html └── index.js ├── 6. Iterators ├── index.html └── index.js └── README.md /1. Callbacks and Higher-Order Functions/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /1. Callbacks and Higher-Order Functions/index.js: -------------------------------------------------------------------------------- 1 | // http://csbin.io/callbacks 2 | console.log("Hello, world!"); 3 | 4 | // Challenge 1 5 | // Create a function addTwo that accepts one input and adds 2 to it. 6 | function addTwo(num) { 7 | return num + 2; 8 | } 9 | 10 | // To check if you've completed it, uncomment these console.logs! 11 | // console.log(addTwo(3)); 12 | // console.log(addTwo(10)); 13 | 14 | // Challenge 2 15 | // Create a function addS that accepts one input and adds an "s" to it. 16 | function addS(word) { 17 | return word + "s"; 18 | } 19 | 20 | // uncomment these to check your work 21 | // console.log(addS("pizza")); 22 | // console.log(addS("bagel")); 23 | 24 | // Challenge 3 25 | /* 26 | Create a function called map that takes two inputs: 27 | 1. an array of numbers (a list of numbers) 28 | 2. a 'callback' function - a function that is applied to each element 29 | of the array (inside of the function 'map') 30 | Have map return a new array filled with numbers that are the result 31 | of using the 'callback' function on each element of the input array. 32 | */ 33 | function map(array, callback) { 34 | //First approach 35 | let output = []; 36 | for (let elem of array) { 37 | output.push(callback(elem)); 38 | } 39 | return output; 40 | 41 | // Second approach 42 | /* return array.map(function(elem) { 43 | return callback(elem)); 44 | }) 45 | */ 46 | } 47 | 48 | // uncomment these to check your work 49 | // console.log(map([1, 2, 3], addTwo)); 50 | 51 | // Challenge 4 52 | /* 53 | The function forEach takes an array and a callback, 54 | and runs the callback on each element of the array. 55 | forEach does not return anything 56 | */ 57 | function forEach(array, callback) { 58 | for (let elem of array) { 59 | callback(elem); 60 | } 61 | } 62 | 63 | // see for yourself if your forEach works! 64 | 65 | /* let alphabet = ''; 66 | let letters = ['a', 'b', 'c', 'd']; 67 | forEach(letters, function(char) { 68 | alphabet += char; 69 | }); 70 | console.log(alphabet); */ 71 | 72 | //-------------------------------------------------- 73 | // Extension 74 | //-------------------------------------------------- 75 | 76 | //Extension 1 77 | /** 78 | * In the first part of the extension, you're going to rebuild map as mapWith. 79 | * This time you're going to use forEach inside of mapWith instead of using a for loop 80 | */ 81 | function mapWith(array, callback) { 82 | let output = []; 83 | 84 | forEach(array, function(elem) { 85 | output.push(callback(elem)); 86 | }); 87 | 88 | return output; 89 | } 90 | 91 | // Test it: 92 | // console.log(mapWith([1, 2, 3], addTwo)); 93 | 94 | //Extension 2 95 | /** 96 | * 97 | The function reduce takes an array and reduces the elements to a single value. 98 | For example it can sum all the numbers, multiply them, or any operation that you can put into a function. 99 | */ 100 | function reduce(array, callback, initialValue) { 101 | for (let elem of array) { 102 | initialValue = callback(initialValue, elem); 103 | } 104 | return initialValue; 105 | } 106 | 107 | // Test it: 108 | /* 109 | let nums = [4, 1, 3]; 110 | let add = function(a, b) { return a + b; } 111 | console.log(reduce(nums, add, 0)); 112 | */ 113 | 114 | //Extension 3 115 | /** 116 | * Construct a function intersection that compares input arrays and returns a new array 117 | * with elements found in all of the inputs. BONUS: Use reduce! 118 | */ 119 | function intersection(...arrays) { 120 | return reduce( 121 | arrays, 122 | (a, b) => { 123 | let result = []; 124 | for (let elem of b) { 125 | if (a.indexOf(elem) > -1) { 126 | result.push(elem); 127 | } 128 | } 129 | return result; 130 | }, 131 | arrays[0] 132 | ); 133 | } 134 | 135 | // Test it! 136 | /* 137 | console.log( 138 | intersection( 139 | [5, 3, 10, 15, 20], 140 | [15, 2, 3, 88, 1, 5, 7], 141 | [1, 3, 10, 15, 5, 20] 142 | ) 143 | );*/ 144 | 145 | // should log: [3, 15, 5] 146 | 147 | //Extension 4 148 | /** 149 | Construct a function union that compares input arrays and returns a new array 150 | that contains all elements. If there are duplicate elements, only add it once to the new array. 151 | Preserve the order of the elements starting from the first element of the first input array. 152 | BONUS: Use reduce! 153 | */ 154 | function union(...arrays) { 155 | return reduce( 156 | arrays, 157 | (a, b) => { 158 | let result = Array.from(a); 159 | for (let elem of b) { 160 | if (a.indexOf(elem) == -1) { 161 | result.push(elem); 162 | } 163 | } 164 | return result; 165 | }, 166 | [] 167 | ); 168 | } 169 | 170 | // Test it! 171 | // console.log(union([5, 10, 15], [15, 88, 1, 5, 7], [100, 15, 10, 1, 5])); 172 | // should log: [5, 10, 15, 88, 1, 7, 100] 173 | 174 | //Extension 5 175 | /** 176 | Construct a function objOfMatches that accepts two arrays and a callback. 177 | objOfMatches will build an object and return it. 178 | To build the object, objOfMatches will test each element of the first array using 179 | the callback to see if the output matches the corresponding element (by index) of the second array. 180 | If there is a match, the element from the first array becomes a key in an object, 181 | and the element from the second array becomes the corresponding value. 182 | */ 183 | function objOfMatches(array1, array2, callback) { 184 | return array1 185 | .map(elem => { 186 | return { [elem]: callback(elem) }; 187 | }) 188 | .filter(elem => array2.indexOf(Object.values(elem)[0]) > -1); 189 | } 190 | 191 | // Test it! 192 | /* 193 | console.log( 194 | objOfMatches( 195 | ["hi", "howdy", "bye", "later", "hello"], 196 | ["HI", "Howdy", "BYE", "LATER", "hello"], 197 | function(str) { 198 | return str.toUpperCase(); 199 | } 200 | ) 201 | ); */ 202 | // should log: { hi: 'HI', bye: 'BYE', later: 'LATER' } 203 | 204 | //Extension 6 205 | /** 206 | Construct a function multiMap that will accept two arrays: 207 | an array of values and an array of callbacks. 208 | multiMap will return an object whose keys match the elements in the array of values. 209 | The corresponding values that are assigned to the keys will be arrays consisting of outputs from the array of callbacks, 210 | where the input to each callback is the key. 211 | */ 212 | function multiMap(arrVals, arrCallbacks) { 213 | let resultArr = arrVals.map(elem => { 214 | let arrayOfNewVals = []; 215 | for (let callback of arrCallbacks) { 216 | arrayOfNewVals.push(callback(elem)); 217 | } 218 | return { [elem]: arrayOfNewVals }; 219 | }); 220 | 221 | return Object.assign({}, ...resultArr); 222 | } 223 | 224 | // Test it! 225 | /* console.log( 226 | multiMap( 227 | ["catfood", "glue", "beer"], 228 | [ 229 | function(str) { 230 | return str.toUpperCase(); 231 | }, 232 | function(str) { 233 | return str[0].toUpperCase() + str.slice(1).toLowerCase(); 234 | }, 235 | function(str) { 236 | return str + str; 237 | } 238 | ] 239 | ) 240 | ); */ 241 | // should log: { catfood: ['CATFOOD', 'Catfood', 'catfoodcatfood'], glue: ['GLUE', 'Glue', 'glueglue'], beer: ['BEER', 'Beer', 'beerbeer'] } 242 | -------------------------------------------------------------------------------- /2. Closure, Scope and ExecutionContext/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /2. Closure, Scope and ExecutionContext/index.js: -------------------------------------------------------------------------------- 1 | // http://csbin.io/closures 2 | 3 | console.log("Hello, world!"); 4 | 5 | // Challenge 1 6 | /** 7 | * Create a function createFunction that creates and returns a function. 8 | * When that created function is called, it should print "hello". 9 | */ 10 | 11 | function createFunction() { 12 | function printHello() { 13 | console.log("hello"); 14 | } 15 | return printHello; 16 | } 17 | 18 | // UNCOMMENT THESE TO TEST YOUR WORK! 19 | // var function1 = createFunction(); 20 | // function1(); 21 | 22 | // Challenge 2 23 | /** 24 | * Create a function createFunctionPrinter that accepts one input and returns 25 | * a function. When that created function is called, it should print out 26 | * the input that was used when the function was created. 27 | */ 28 | function createFunctionPrinter(input) { 29 | function printInput() { 30 | console.log(input); 31 | } 32 | return printInput; 33 | } 34 | 35 | // UNCOMMENT THESE TO TEST YOUR WORK! 36 | // var printSample = createFunctionPrinter("sample"); 37 | // printSample(); 38 | // var printHello = createFunctionPrinter("hello"); 39 | // printHello(); 40 | 41 | // Challenge 3 42 | /** 43 | * Examine the code for the outer function. Notice that we are returning 44 | * a function and that function is using variables that are outside of its scope. 45 | * Uncomment those lines of code. Try to deduce the output before executing. 46 | */ 47 | 48 | function outer() { 49 | var counter = 0; // this variable is outside incrementCounter's scope 50 | function incrementCounter() { 51 | counter++; 52 | console.log("counter", counter); 53 | } 54 | return incrementCounter; 55 | } 56 | 57 | var willCounter = outer(); 58 | var jasCounter = outer(); 59 | 60 | // Uncomment each of these lines one by one. 61 | // Before your do, guess what will be logged from each function call. 62 | 63 | // willCounter(); 64 | // willCounter(); 65 | // willCounter(); 66 | 67 | // jasCounter(); 68 | // willCounter(); 69 | 70 | // Challenge 4 71 | /** 72 | * Now we are going to create a function addByX that returns a function 73 | * that will add an input by x 74 | */ 75 | 76 | function addByX(x) { 77 | function add(num) { 78 | return x + num; 79 | } 80 | return add; 81 | } 82 | 83 | var addByTwo = addByX(2); 84 | 85 | // UNCOMMENT THESE TO TEST YOUR WORK! 86 | // addByTwo(1); //should return 3 87 | // addByTwo(2); //should return 4 88 | // addByTwo(3); //should return 5 89 | 90 | // var addByThree = addByX(3); 91 | // addByThree(1); //should return 4 92 | // addByThree(2); //should return 5 93 | 94 | // var addByFour = addByX(4); 95 | // addByFour(4); //should return 8 96 | // addByFour(10); //should return 14 97 | 98 | //-------------------------------------------------- 99 | // Extension 100 | //-------------------------------------------------- 101 | 102 | // Challenge 5 103 | /** 104 | Write a function once that accepts a callback as input and returns 105 | a function. When the returned function is called the first time, 106 | it should call the callback and return that output. 107 | If it is called any additional times, instead of calling the callback 108 | again it will simply return the output value from the first time it was called. 109 | */ 110 | function once(func) { 111 | let counter = 0; 112 | let result; 113 | function callCallback(num) { 114 | counter++; 115 | return counter < 2 ? (result = func(num)) : result; 116 | } 117 | return callCallback; 118 | } 119 | 120 | var onceFunc = once(addByTwo); 121 | 122 | // UNCOMMENT THESE TO TEST YOUR WORK! 123 | // console.log(onceFunc(4)); //should log 6 124 | // console.log(onceFunc(10)); //should log 6 125 | // console.log(onceFunc(9001)); //should log 6 126 | 127 | // Challenge 6 128 | /** 129 | * Write a function after that takes the number of times the callback 130 | * needs to be called before being executed as the first parameter 131 | * and the callback as the second parameter. 132 | */ 133 | 134 | function after(count, func) { 135 | let counter = 0; 136 | function executeCallback() { 137 | counter++; 138 | if (counter >= count) { 139 | return func(); 140 | } 141 | } 142 | return executeCallback; 143 | } 144 | 145 | var called = function() { 146 | console.log("hello"); 147 | }; 148 | var afterCalled = after(3, called); 149 | 150 | // UNCOMMENT THESE TO TEST YOUR WORK! 151 | // afterCalled(); // -> nothing is printed 152 | // afterCalled(); // -> 'hello' is printed 153 | // afterCalled(); // -> nothing is printed 154 | 155 | /** 156 | * Write a function delay that accepts a callback as the first parameter 157 | * and the wait in milliseconds before allowing the callback to be invoked 158 | * as the second parameter. 159 | * Any additional arguments after wait are provided to func 160 | * when it is invoked. 161 | */ 162 | 163 | function delay(func, wait) { 164 | setTimeout(() => func(), wait); 165 | } 166 | 167 | delay(function printHi() { 168 | console.log("Hi"); 169 | }, 1000); 170 | -------------------------------------------------------------------------------- /3. Async/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /3. Async/index.js: -------------------------------------------------------------------------------- 1 | // http://csbin.io/async 2 | 3 | /* CHALLENGE 1 */ 4 | /** 5 | * Thinking point (no writing code necessary for this challenge): 6 | * Inspect the code given to you in Challenge 1. 7 | * In what order should the console logs come out? 8 | * Howdy first or Partnah first? 9 | */ 10 | 11 | function sayHowdy() { 12 | console.log("Howdy"); 13 | } 14 | 15 | function testMe() { 16 | setTimeout(sayHowdy, 0); 17 | console.log("Partnah"); 18 | } 19 | // After thinking it through, uncomment the following line to check your guess! 20 | // testMe(); // what order should these log out? Howdy or Partnah first? 21 | 22 | /* CHALLENGE 2 */ 23 | /** 24 | * Create a function delayedGreet that console logs welcome after 3 seconds. 25 | */ 26 | function delayedGreet() { 27 | setTimeout(() => console.log("welcome"), 3000); 28 | } 29 | // Uncomment the following line to check your work! 30 | // delayedGreet(); // should log (after 3 seconds): welcome 31 | 32 | /* CHALLENGE 3 */ 33 | /** 34 | * Create a function helloGoodbye that console logs hello right away, 35 | * and good bye after 2 seconds. 36 | */ 37 | 38 | function helloGoodbye() { 39 | console.log("hello"); 40 | setTimeout(() => console.log("good bye"), 2000); 41 | } 42 | // Uncomment the following line to check your work! 43 | // helloGoodbye(); // should log: hello // should also log (after 3 seconds): good bye 44 | 45 | /* CHALLENGE 4 */ 46 | /** 47 | * Create a function brokenRecord that console logs hi again every second. 48 | * Use the End Code button to stop the console logs when you are 49 | * satisfied that it is working. 50 | */ 51 | 52 | function brokenRecord() { 53 | let done = false; 54 | 55 | setInterval(() => { 56 | if (!done) console.log("hi again"); 57 | }, 1000); 58 | 59 | window.addEventListener("keypress", e => { 60 | if (e.keyCode === 13) { 61 | done = true; 62 | } 63 | }); 64 | } 65 | // Uncomment the following line to check your work! 66 | // brokenRecord(); // should log (every second): hi again 67 | 68 | /* CHALLENGE 5 */ 69 | /** 70 | * Create a function limitedRepeat that console logs hi for now every 71 | * second, but only for 5 seconds. 72 | * Research how to use clearInterval if you are not sure how to do this. 73 | */ 74 | 75 | function limitedRepeat() { 76 | let counter = 0; 77 | let printEverySecond = setInterval(() => { 78 | console.log("hi for now"); 79 | counter++; 80 | if (counter > 4) { 81 | clearInterval(printEverySecond); 82 | } 83 | }, 1000); 84 | } 85 | // Uncomment the following line to check your work! 86 | // limitedRepeat(); // should log (every second, for 5 seconds): hi for now 87 | 88 | /* CHALLENGE 6 */ 89 | /** 90 | * Write a function called everyXsecsForYsecs that will accept three arguments: 91 | * a function func, 92 | * a number interval, 93 | * and another number duration. 94 | * everyXsecsForYsecs will execute the given function every interval 95 | * number of milliseconds, but then automatically stop after 96 | * duration milliseconds. 97 | * Then pass the below sayHi function into an invocation of everyXsecsForYsecs 98 | * with 1000 interval time an 5000 duration time. 99 | * What do you expect to happen? 100 | */ 101 | 102 | function everyXsecsForYsecs(callback, interval, duration) { 103 | let counter = 0; 104 | let executeCallback = setInterval(() => { 105 | if (counter < duration) { 106 | callback(); 107 | } 108 | counter++; 109 | }, interval * 1000); 110 | } 111 | // Uncomment the following lines to check your work! 112 | // function theEnd() { 113 | // console.log("This is the end!"); 114 | // } 115 | // everyXsecsForYsecs(theEnd, 2, 20); // should invoke theEnd function every 2 seconds, for 20 seconds): This is the end! 116 | -------------------------------------------------------------------------------- /4. OOP/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /4. OOP/index.js: -------------------------------------------------------------------------------- 1 | // http://csbin.io/oop 2 | console.log("Hello, world!"); 3 | 4 | /**************************************************************** 5 | WORKING WITH OBJECT LITERALS 6 | ****************************************************************/ 7 | 8 | /*** CHALLENGE 1 of 1 ***/ 9 | /** 10 | * Create a function that accepts two inputs (name and age) and returns an object. 11 | * Let's call this function makePerson. This function will: 12 | * create an empty object 13 | * add a name property to the newly created object with its value being the 'name' argument passed into the function 14 | * add an age property to the newly created object with its value being the 'age' argument passed into the function 15 | * return the object 16 | */ 17 | 18 | function makePerson(name, age) { 19 | let person = {}; 20 | person.name = name; 21 | person.age = age; 22 | return person; 23 | } 24 | 25 | var vicky = makePerson("Vicky", 24); 26 | 27 | // /********* Uncomment these lines to test your work! *********/ 28 | // console.log(vicky.name); // -> Logs 'Vicky' 29 | // console.log(vicky.age); // -> Logs 24 30 | 31 | /**************************************************************** 32 | USING OBJECT.CREATE 33 | ****************************************************************/ 34 | 35 | /*** CHALLENGE 1 of 3 ***/ 36 | /** 37 | * Inside personStore object, create a property greet where the value 38 | * is a function that logs "hello". 39 | */ 40 | 41 | var personStore = { 42 | greet: function() { 43 | console.log("hello"); 44 | } 45 | }; 46 | 47 | // /********* Uncomment this line to test your work! *********/ 48 | // personStore.greet(); // -> Logs 'hello' 49 | 50 | /*** CHALLENGE 2 of 3 ***/ 51 | /** 52 | * Create a function personFromPersonStore that takes as input a name and an age. 53 | * When called, the function will create person objects using the Object.create 54 | * method on the personStore object. 55 | */ 56 | 57 | function personFromPersonStore(name, age) { 58 | let person = Object.create(personStore); 59 | person.name = name; 60 | person.age = age; 61 | return person; 62 | } 63 | 64 | var sandra = personFromPersonStore("Sandra", 26); 65 | 66 | // /********* Uncomment these lines to test your work! *********/ 67 | // console.log(sandra.name); // -> Logs 'Sandra' 68 | // console.log(sandra.age); //-> Logs 26 69 | // sandra.greet(); //-> Logs 'hello' 70 | 71 | /*** CHALLENGE 3 of 3 ***/ 72 | /** 73 | * Without editing the code you've already written, 74 | * add an introduce method to the personStore object that logs "Hi, 75 | * my name is [name] 76 | */ 77 | 78 | // add code here 79 | personStore.introduce = function() { 80 | console.log("Hi, my name is " + this.name); 81 | }; 82 | 83 | // sandra.introduce(); // -> Logs 'Hi, my name is Sandra' 84 | 85 | /**************************************************************** 86 | USING THE 'NEW' KEYWORD 87 | ****************************************************************/ 88 | 89 | /*** CHALLENGE 1 of 3 ***/ 90 | /** 91 | * Create a function PersonConstructor that uses the this keyword to save 92 | * a single property onto its scope called greet. greet should be a function that logs 93 | * the string 'hello' 94 | */ 95 | 96 | function PersonConstructor() { 97 | this.greet = function() { 98 | console.log("hello"); 99 | }; 100 | this.introduce = function() { 101 | console.log("Hi, my name is " + this.name); 102 | }; 103 | } 104 | 105 | // /********* Uncomment this line to test your work! *********/ 106 | var simon = new PersonConstructor(); 107 | // simon.greet(); // -> Logs 'hello' 108 | 109 | /*** CHALLENGE 2 of 3 ***/ 110 | /** 111 | * personFromConstructor that takes as input a name and an age. 112 | * When called, the function will create person objects using the new keyword 113 | * instead of the Object.create method. 114 | */ 115 | 116 | function personFromConstructor(name, age) { 117 | let person = new PersonConstructor(); 118 | person.name = name; 119 | person.age = age; 120 | return person; 121 | } 122 | 123 | var mike = personFromConstructor("Mike", 30); 124 | 125 | // /********* Uncomment these lines to test your work! *********/ 126 | // console.log(mike.name); // -> Logs 'Mike' 127 | // console.log(mike.age); //-> Logs 30 128 | // mike.greet(); //-> Logs 'hello' 129 | 130 | /*** CHALLENGE 3 of 3 ***/ 131 | /** 132 | * Without editing the code you've already written, add an introduce 133 | * method to the PersonConstructor function that logs 134 | * "Hi, my name is [name]" 135 | */ 136 | 137 | // mike.introduce(); // -> Logs 'Hi, my name is Mike' 138 | 139 | /**************************************************************** 140 | USING ES6 CLASSES 141 | ****************************************************************/ 142 | 143 | /*** CHALLENGE 1 of 2 ***/ 144 | /** 145 | * Create a class PersonClass. 146 | * PersonClass should have a constructor that is passed an input 147 | * of name and saves it to a property by the same name. 148 | * PersonClass should also have a method called greet 149 | * that logs the string 'hello'. 150 | */ 151 | 152 | class PersonClass { 153 | constructor(name) { 154 | this.name = name; 155 | } 156 | 157 | greet() { 158 | console.log("hello"); 159 | } 160 | } 161 | 162 | // /********* Uncomment this line to test your work! *********/ 163 | var george = new PersonClass(); 164 | // george.greet(); // -> Logs 'hello' 165 | 166 | /*** CHALLENGE 2 of 2 ***/ 167 | /** 168 | * Create a class DeveloperClass that creates objects by extending 169 | * the PersonClass class. 170 | * In addition to having a name property and greet method, 171 | * DeveloperClass should have an introduce method. 172 | * When called, introduce should log the string 173 | * 'Hello World, my name is [name]'. 174 | */ 175 | 176 | class DeveloperClass extends PersonClass { 177 | constructor(name) { 178 | super(name); 179 | } 180 | introduce() { 181 | console.log("Hello World, my name is " + this.name); 182 | } 183 | } 184 | 185 | // /********* Uncomment these lines to test your work! *********/ 186 | var thai = new DeveloperClass("Thai", 32); 187 | // console.log(thai.name); // -> Logs 'Thai' 188 | // thai.introduce(); //-> Logs 'Hello World, my name is Thai' 189 | 190 | /**************************************************************** 191 | EXTENSION: SUBCLASSING 192 | ****************************************************************/ 193 | 194 | var userFunctionStore = { 195 | sayType: function() { 196 | console.log("I am a " + this.type); 197 | } 198 | }; 199 | 200 | function userFactory(name, score) { 201 | let user = Object.create(userFunctionStore); 202 | user.type = "User"; 203 | user.name = name; 204 | user.score = score; 205 | return user; 206 | } 207 | 208 | /** Challenge 1 */ 209 | /** 210 | * Create an object adminFunctionStore that has access to all methods 211 | * in the userFunctionStore object, without copying them over individually. 212 | */ 213 | 214 | /** Challenge 5 */ 215 | /** 216 | * Created a method called sharePublicMessage that logs 'Welcome users!' 217 | * and will be available to adminFactory objects, 218 | * but not userFactory objects. 219 | * Do not add this method directly in the adminFactory function. 220 | */ 221 | 222 | var adminFunctionStore = Object.create(userFunctionStore, { 223 | sharePublicMessage: { 224 | value: function() { 225 | console.log("Welcome users!"); 226 | } 227 | } 228 | }); 229 | 230 | /** Challenge 2 */ 231 | /** 232 | * Create an adminFactory function that creates an object 233 | * with all the same data fields (and default values) as objects 234 | * of the userFactory class, but without copying each data field individually. 235 | */ 236 | 237 | function adminFactory(name, score) { 238 | let adminDefault = userFactory.call(this, name, score); 239 | let admin = Object.create(adminFunctionStore, { 240 | name: { 241 | value: name 242 | }, 243 | score: { 244 | value: score 245 | } 246 | }); 247 | 248 | /** Challenge 3 */ 249 | /** 250 | * Then make sure the value of the 'type' field for adminFactory 251 | * objects is 'Admin' instead of 'User'. 252 | */ 253 | 254 | admin.type = "Admin"; 255 | 256 | return admin; 257 | } 258 | 259 | /** Challenge 4 */ 260 | /** 261 | * Make sure that adminFactory objects have access to adminFunctionStore 262 | * methods, without copying them over. 263 | */ 264 | 265 | var user = userFactory("Steve", 10); 266 | var admin = adminFactory("Eva", 5); 267 | 268 | console.log(admin); 269 | console.log(user); 270 | 271 | // /********* Uncomment these lines to test your work! *********/ 272 | admin.sayType(); // -> Logs "I am a Admin" 273 | user.sayType(); // -> Logs "I am a User" 274 | admin.sharePublicMessage(); // -> Logs "Welcome users!" 275 | -------------------------------------------------------------------------------- /5. Promises/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /5. Promises/index.js: -------------------------------------------------------------------------------- 1 | // http://csbin.io/promises 2 | 3 | // Challenge 1 4 | /** 5 | * Let's start by reviewing asynchronous functions! Using setTimeout, print the string 'Hello!' after 1000ms. 6 | */ 7 | function sayHello() { 8 | setTimeout(function() { 9 | console.log("1. Hello!"); 10 | }, 1000); 11 | } 12 | 13 | // Uncomment the line below when ready 14 | sayHello(); // should log "Hello" after 1000ms 15 | 16 | // Challenge 2 17 | /** 18 | * Create a promise. Have it resolve with a value of 'Resolved!' in resolve after a delay of 1000ms, using setTimeout. 19 | * Print the contents of the promise after it has been resolved by passing console.log to .then 20 | */ 21 | var promise = new Promise(function(resolve, reject) { 22 | // ADD CODE HERE 23 | setTimeout(() => resolve("2. Resolved!"), 1000); 24 | }); 25 | 26 | // Should print out "Resolved!" 27 | // ADD CODE HERE 28 | 29 | promise.then(data => console.log(data)); 30 | 31 | // Challenge 3 32 | /** 33 | * Create another promise. Now have it reject with a value of "Rejected!" without using setTimeout. 34 | * Print the contents of the promise after it has been rejected by passing console.log to .catch 35 | */ 36 | promise = new Promise(function(resolve, reject) { 37 | // ADD CODE HERE 38 | reject("3. Rejected!"); 39 | }); 40 | 41 | // Should print out "Reject!" 42 | // ADD CODE HERE 43 | promise.catch(data => console.log(data)); 44 | 45 | // Challenge 4 46 | /** 47 | * Promises are asynchronous and we're now going to prove that they indeed are! 48 | * Create a promise and have it resolve with the value of "Promise has been resolved!" 49 | * Then uncomment the code at bottom of Challenge 4. 50 | * What order do we expect "Promise has been resolved!" and "I'm not the promise!" to print? Why? 51 | */ 52 | 53 | promise = new Promise(function(resolve, reject) { 54 | // ADD CODE HERE 55 | resolve("4. Promise has been resolved"); 56 | }); 57 | 58 | // Uncomment the lines below when ready 59 | promise.then(data => console.log(data)); 60 | console.log("4. I'm not the promise!"); 61 | 62 | // Challenge 5 63 | /** 64 | * Write a function delay that returns a promise. And that promise should return a setTimeout that calls resolve after 1000ms 65 | */ 66 | function delay() { 67 | return new Promise((resolve, reject) => { 68 | setTimeout(() => resolve("5. Hello"), 1000); 69 | }); 70 | } 71 | 72 | // Uncomment the code below to test 73 | // This code should log "Hello" after 1000ms 74 | function sayHello(data) { 75 | console.log(data); 76 | } 77 | 78 | delay().then(sayHello); 79 | 80 | // Challenge 6 81 | /** 82 | * This challenge we'll chain promises together using ".then" Create two variables: firstPromise and secondPromise 83 | * Set secondPromise to be a promise that resolves to "Second!" Set firstPromise to be a promise that resolves to secondPromise 84 | * Call the firstPromise with a ".then", which will return the secondPromise> promise. 85 | * Then print the contents of the promise after it has been resolved by passing console.log to .then 86 | */ 87 | // 88 | // ADD CODE BELOW 89 | var secondPromise = new Promise((resolve, reject) => { 90 | resolve("6. Second"); 91 | }); 92 | 93 | var firstPromise = new Promise((resolve, reject) => { 94 | resolve(secondPromise); 95 | }); 96 | 97 | firstPromise.then(data => console.log(data)); 98 | 99 | // Challenge 7 100 | /** 101 | * We have a API that gets data from a database, it takes an index parameter and returns a promise 102 | * Your challenge is to use Promise.all to make 3 API calls and return all the data when the calls are complete 103 | */ 104 | const fakePeople = [ 105 | { name: "Rudolph", hasPets: false, currentTemp: 98.6 }, 106 | { name: "Zebulon", hasPets: true, currentTemp: 22.6 }, 107 | { name: "Harold", hasPets: true, currentTemp: 98.3 } 108 | ]; 109 | 110 | const fakeAPICall = i => { 111 | const returnTime = Math.floor(Math.random() * 1000); 112 | return new Promise((resolve, reject) => { 113 | if (i >= 0 && i < fakePeople.length) { 114 | setTimeout(() => resolve(fakePeople[i]), returnTime); 115 | } else { 116 | reject({ message: "index out of range" }); 117 | } 118 | }); 119 | }; 120 | 121 | function getAllData() { 122 | // CODE GOES HERE 123 | Promise.all([fakeAPICall(0), fakeAPICall(1), fakeAPICall(2)]).then(data => console.log(data)); 124 | } 125 | 126 | getAllData(); 127 | -------------------------------------------------------------------------------- /6. Iterators/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /6. Iterators/index.js: -------------------------------------------------------------------------------- 1 | // http://csbin.io/iterators 2 | 3 | // Type JavaScript here and click "Run Code" or press Ctrl + s 4 | console.log("Hello, world!"); 5 | 6 | // CHALLENGE 1 7 | /* 8 | A) Create a for loop that iterates through an array and returns the sum of the elements of the array. 9 | B) Create a functional iterator for an array that returns each value of the array when called, one element at a time. 10 | */ 11 | function sumFunc(arr) { 12 | // YOUR CODE HERE 13 | let sum = 0; 14 | for (let i = 0; i < arr.length; i++) { 15 | sum += arr[i]; 16 | } 17 | return sum; 18 | } 19 | 20 | // Uncomment the lines below to test your work 21 | const array = [1, 2, 3, 4]; 22 | console.log(sumFunc(array)); // -> should log 10 23 | 24 | function returnIterator(arr) { 25 | // YOUR CODE HERE 26 | let i = 0; 27 | return function() { 28 | let elem = arr[i]; 29 | i++; 30 | return elem; 31 | }; 32 | } 33 | 34 | // Uncomment the lines below to test your work 35 | const array2 = ["a", "b", "c", "d"]; 36 | const myIterator = returnIterator(array2); 37 | console.log(myIterator()); // -> should log 'a' 38 | console.log(myIterator()); // -> should log 'b' 39 | console.log(myIterator()); // -> should log 'c' 40 | console.log(myIterator()); // -> should log 'd' 41 | 42 | // CHALLENGE 2 43 | /** 44 | * Create an iterator with a next method that returns each value of the array when .next is called. 45 | */ 46 | 47 | function nextIterator(arr) { 48 | // YOUR CODE HERE 49 | let i = 0; 50 | return { 51 | next: function () { 52 | let elem = arr[i]; 53 | i++; 54 | return elem; 55 | }, 56 | current: function () { 57 | if (i >= arr.length) return null; 58 | return arr[i]; 59 | }, 60 | }; 61 | } 62 | 63 | // Uncomment the lines below to test your work 64 | const array3 = [1, 2, 3]; 65 | const iteratorWithNext = nextIterator(array3); 66 | console.log(iteratorWithNext.next()); // -> should log 1 67 | console.log(iteratorWithNext.next()); // -> should log 2 68 | console.log(iteratorWithNext.next()); // -> should log 3 69 | 70 | // CHALLENGE 3 71 | /** 72 | * Write code to iterate through an entire array using your nextIterator and sum the values. 73 | */ 74 | 75 | function sumArray(arr) { 76 | // YOUR CODE HERE 77 | // use your nextIterator function 78 | let sum = 0; 79 | const iterate = nextIterator(arr); 80 | while (iterate.current() !== null) { 81 | sum += iterate.next(); 82 | } 83 | return sum; 84 | } 85 | 86 | // Uncomment the lines below to test your work 87 | const array4 = [1, 2, 3, 4]; 88 | console.log(sumArray(array4)); // -> should log 10 89 | 90 | // CHALLENGE 4 91 | 92 | /** 93 | * Create an iterator with a next method that returns each value of a set when .next is called 94 | */ 95 | function setIterator(set) { 96 | // YOUR CODE HERE 97 | let it = set.values(); 98 | return { 99 | next: function() { 100 | return it.next().value; 101 | } 102 | }; 103 | } 104 | 105 | // Uncomment the lines below to test your work 106 | const mySet = new Set("hey"); 107 | const iterateSet = setIterator(mySet); 108 | console.log(iterateSet.next()); // -> should log 'h' 109 | console.log(iterateSet.next()); // -> should log 'e' 110 | console.log(iterateSet.next()); // -> should log 'y' 111 | 112 | // CHALLENGE 5 113 | /** 114 | * Create an iterator with a next method that returns an array with two elements 115 | * (where the first element is the index and the second is the value at that index) when .next is called. 116 | */ 117 | 118 | function indexIterator(arr) { 119 | // YOUR CODE HERE 120 | let i = 0; 121 | return { 122 | next: function() { 123 | let elem = [i, arr[i]]; 124 | i++; 125 | return elem; 126 | } 127 | }; 128 | } 129 | 130 | // Uncomment the lines below to test your work 131 | const array5 = ["a", "b", "c", "d"]; 132 | const iteratorWithIndex = indexIterator(array5); 133 | console.log(iteratorWithIndex.next()); // -> should log [0, 'a'] 134 | console.log(iteratorWithIndex.next()); // -> should log [1, 'b'] 135 | console.log(iteratorWithIndex.next()); // -> should log [2, 'c'] 136 | 137 | // CHALLENGE 6 138 | /** 139 | * Create an iterator that returns each word from a string of words on the call of its .next method (hint: use regex!) 140 | Then attach it as a method to the prototype of a constructor Words. Hint: research Symbol.iterator! 141 | */ 142 | 143 | function Words(string) { 144 | this.str = string; 145 | return this.str.split(" "); 146 | } 147 | 148 | Words.prototype[Symbol.iterator] = function() { 149 | // YOUR CODE HERE 150 | let i = 0; 151 | return { 152 | next: function() { 153 | let elem = this[i]; 154 | i++; 155 | return elem; 156 | } 157 | }; 158 | }; 159 | 160 | // Uncomment the lines below to test your work 161 | const helloWorld = new Words("Hello World"); 162 | for (word of helloWorld) { 163 | console.log(word); 164 | } // -> should log 'Hello' and 'World' 165 | 166 | // CHALLENGE 7 167 | 168 | /** 169 | * Build a function that walks through an array and returns the element concatenated 170 | * with the string "was found after index x", where x is the previous index. 171 | Note: if it is the first element it should say that it is the first 172 | */ 173 | 174 | function valueAndPrevIndex(array) { 175 | let i = 0; 176 | return { 177 | sentence: function() { 178 | i++; 179 | if (i === 1) { 180 | return "that is the first element"; 181 | } 182 | return `${array[i - 1]} was found after index ${i - 2}`; 183 | } 184 | }; 185 | } 186 | 187 | const returnedSentence = valueAndPrevIndex([4, 5, 6]); 188 | console.log(returnedSentence.sentence()); 189 | console.log(returnedSentence.sentence()); 190 | console.log(returnedSentence.sentence()); 191 | 192 | //CHALLENGE 8 193 | /** 194 | * Write a function that will console.log "hello there", or "gibberish", every three seconds depending on if the word passed into the function is 'english'. 195 | Do not use any type of loop constructor and only make the call to createConversation once. 196 | */ 197 | 198 | function* createConversation(str) { 199 | yield setInterval(function() { 200 | if (str == "english") { 201 | console.log("hello there"); 202 | } else { 203 | console.log("gibberish"); 204 | } 205 | }, 3000); 206 | } 207 | 208 | createConversation("english").next(); 209 | 210 | //CHALLENGE 9 211 | /** 212 | * Use async/await to console.log a sentence comprised of a noun and verb in which the non async function takes in a noun, 213 | * concatenates it with a hard coded verb and returns it to the async function to be console.logged after a duration of 3 seconds. 214 | * Call the async function only once, feeding it a noun to make this happen 215 | */ 216 | function waitForVerb(noun) { 217 | const verb = "play"; 218 | return new Promise((resolve, reject) => { 219 | setTimeout(() => resolve(noun + " " + verb), 3000); 220 | }) 221 | } 222 | 223 | async function f(noun) { 224 | const data = await waitForVerb(noun); 225 | console.log(data); 226 | } 227 | 228 | f("dog"); 229 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Completed challenges from js-hard-parts course from frontendmasters 2 | 3 | 4 | 1. Callbacks and Higher-Order Functions contains set of completed tasks from http://csbin.io/callbacks 5 | 2. Closures, Scope, and ExecutionContext contains set of completed tasks from http://csbin.io/closures 6 | 3. Async contains set of completed tasks from http://csbin.io/async 7 | 4. OOP contains set of completed tasks from http://csbin.io/oop 8 | 5. Promises contains set of completed tasks from http://csbin.io/promises 9 | 6. Iterators contains set of completed tasks from http://csbin.io/iterators 10 | 11 | 12 | Note: For practise first try to complete challenges, from the above links, by yourself, don't immediately look for solutions 13 | --------------------------------------------------------------------------------