├── 1-hoisting └── README.md ├── 2-higher-order-functions └── README.md ├── 3-scopes ├── README.md ├── SpecRunner.html ├── functions.js └── lib │ ├── chai │ └── chai.js │ └── mocha │ ├── mocha.css │ └── mocha.js └── README.md /1-hoisting/README.md: -------------------------------------------------------------------------------- 1 | # Part I: Hoisting 2 | 3 | *Note: Before getting started on these exercises, please be certain that you've read through the root [README.md](../README.md) file in this repository.* 4 | 5 | In order to complete these exercises, open [repl.it](https://repl.it/), choose JavaScript, and then write your code in the left-hand panel. You can run your code using the "Run" button. 6 | 7 | ### Two Forms of Functions 8 | 9 | ```js 10 | // function declaration 11 | function square(x) { 12 | return x * x; 13 | } 14 | 15 | // function expression 16 | var square = function(x) { 17 | return x * x; 18 | }; 19 | ``` 20 | 21 | ## Exercises 22 | 23 | ### Basic Requirements 24 | 25 | #### Rewrite Functions 26 | 27 | Rewrite the following *function declarations* using a *function expression*: 28 | 29 | ```js 30 | // 1. 31 | function cube(x) { 32 | return x * x * x; 33 | } 34 | 35 | // 2. 36 | function fullName(first, last) { 37 | return first + " " + last; 38 | } 39 | 40 | // 3. 41 | function power(base, exp) { 42 | if (exp === 0) { 43 | return 1; 44 | } 45 | return base * power(base, exp - 1); 46 | } 47 | 48 | // 4. 49 | function sumCubes(numbers) { 50 | var total = 0; 51 | for (var i = 0; i < numbers.length; i++) { 52 | total = total + cube(numbers[i]); 53 | } 54 | return total; 55 | } 56 | ``` 57 | #### Mechanics of Hoisting 58 | 59 | Type out your best answers to the following questions: 60 | 61 | 1. Why does JavaScript output `undefined` instead of throwing an error in the following code? 62 | 63 | ```js 64 | console.log(message); 65 | 66 | var message = 'Hi there!'; 67 | ``` 68 | 69 | 2. Why does JavaScript throw an error instead of logging `undefined` in the following code? 70 | 71 | ```js 72 | console.log(message); 73 | 74 | let message = 'Hi there!'; 75 | ``` 76 | 77 | 3. Explain precisely what happens when the following code is executed. 78 | 79 | ```js 80 | console.log(showMessage()); 81 | 82 | var showMessage = function(){ 83 | return 'Hi there!'; 84 | }; 85 | ``` 86 | 87 | 4. Why does JavaScript *not* throw any errors when the following code is executed? 88 | 89 | ```js 90 | console.log(showMessage()); 91 | 92 | function showMessage(){ 93 | return 'Hi there!'; 94 | } 95 | ``` 96 | 97 | #### Code Restructuring 98 | 99 | Restructure the following instances of code to work correctly: 100 | 101 | ```js 102 | // 1. 103 | for(var i = 0; i < values.length; i++){ 104 | console.log(values[i]); 105 | } 106 | 107 | var values = [10, 20, 30]; 108 | ``` 109 | ```js 110 | // 2. 111 | console.log(welcome('Charlie', 'Munger')); 112 | 113 | function welcome(first, last) { 114 | return `Welcome, ${first} ${last}! You last logged in on ${lastLogin}.` 115 | }; 116 | 117 | var lastLogin = '1/1/1970'; 118 | ``` 119 | -------------------------------------------------------------------------------- /2-higher-order-functions/README.md: -------------------------------------------------------------------------------- 1 | # Part II: Higher-Order Functions 2 | 3 | *Note: Before getting started on these exercises, please be certain that you've read through the root [README.md](../README.md) file in this repository.* 4 | 5 | In order to complete these exercises, open [repl.it](https://repl.it/), choose JavaScript, and then write your code in the left-hand panel. You can run your code using the "Run" button. 6 | 7 | ## Exercises 8 | 9 | ### Basic Requirements 10 | 11 | #### Iterating Over Arrays Using `each` 12 | 13 | 1. Write `each` as seen below in your code editor (Do not just copy-paste!) 14 | 15 | ```js 16 | function each(array, func) { 17 | for (var i = 0; i < array.length; i++) { 18 | func(array[i]); 19 | } 20 | } 21 | ``` 22 | 23 | 2. Finish the implementation of `sumSquares` below (using above `each` function): 24 | 25 | ```js 26 | function sumSquares(numbers) { 27 | var total = 0; 28 | // ... 29 | return total; 30 | } 31 | ``` 32 | 33 | 3. Rewrite `sumCubes` using `each`: 34 | 35 | ```js 36 | function sumCubes(numbers) { 37 | var total = 0; 38 | for (var i = 0; i < numbers.length; i++) { 39 | total = total + cube(numbers[i]); 40 | } 41 | return total; 42 | } 43 | ``` 44 | 45 | 3. Write a function called `product` that calculates the product of an array of 46 | numbers using a `for` loop; then, refactor it to use `each`. 47 | 48 | 4. Write a function called `cubeAll` that cubes each number in an array, and 49 | returns an array of all the numbers *cubed* using a `for` loop; then, 50 | refactor it to use `each`. 51 | 52 | 5. Write a function called `odds` that accepts an array as a parameter and 53 | returns an array of just the odd numbers. 54 | 55 | ### More Practice 56 | 57 | #### Summations 58 | 59 | 1. Write a function `sumByAllElementsMultipliedByFour` that takes an array as an 60 | argument and returns the sum of all elements multiplied by four. 61 | 62 | 2. Observe that `sumByAllElementsMultipliedByFour` is a terrible name for a 63 | function – you should also notice that `sumByAllElementsMultipliedByFour` 64 | looks a lot like `sumCubes` and `sumSquares`. 65 | 66 | Write a function `sumBy` that accepts two arguments: an array of numbers and 67 | a *function*. The function will be invoked upon each element in the array, 68 | and its result will be used to compute the sum. 69 | 70 | ```js 71 | function sumBy(numbers, f) { 72 | // ... 73 | } 74 | var numbers = [1, 2, 3, 4]; 75 | sumBy(numbers, square); // => 30 76 | sumBy(numbers, cube); // => 100 77 | sumBy(numbers, function(number) { 78 | return number * 4; 79 | }); 80 | // => 40 81 | ``` 82 | 83 | 3. How can you use `sumBy` to compute the sum of an array of 84 | numbers (just the plain sum)? 85 | 86 | 4. Write a function `productBy` that works like `sumBy`, but for **products**. 87 | 88 | #### Refactoring 89 | 90 | *If you've attended prior lessons:* As an extended exercise, run back through your code from the past lessons and look for opportunities to refactor your use of `for` loops using 91 | `each`, `map` and `filter`. 92 | 93 | ### Advanced 94 | 95 | #### Finding Patterns: Mapping 96 | 97 | 1. Write a function `doubleAll` that takes an array of numbers as a parameter 98 | and returns an array of all of those numbers *doubled*: 99 | 100 | ```js 101 | function doubleAll(numbers) { 102 | // ... 103 | } 104 | doubleAll([1, 3, 10, 4, 7]); // => [2, 6, 20, 8, 14] 105 | ``` 106 | 107 | 2. Write a function `halveAll` that takes an array of numbers as a parameter and 108 | returns an array of all of those numbers *halved* (divided by two). 109 | 110 | 3. Write a function `uppercaseAll` that takes an array of **strings** as a 111 | parameter, and returns an array of all of those strings, but transformed to 112 | *upper case*. You can use `toUpperCase` to convert a string to upper case. 113 | 114 | ```js 115 | "hello, world".toUpperCase(); // => "HELLO, WORLD" 116 | ``` 117 | 118 | 119 | 4. You should at this point notice a similarity between all of the above 120 | functions, as well as the `cubeAll` function from the warmup. These functions 121 | all define what we call **mappings**; that is, they *map* from one value to 122 | another. 123 | 124 | ```js 125 | // doubleAll maps from an array of numbers to an array of doubled numbers 126 | // [1, 2, 3, 4] => [2, 4, 6, 8] 127 | 128 | // halveAll maps from an array of numbers to an array of halved numbers 129 | // [1, 2, 3, 4] => [0.5, 1, 1.5, 2] 130 | ``` 131 | 132 | 5. Write a function `map` that takes two parameters: an array and a *function* 133 | that, when applied to a single element, produces a new element. `map` should 134 | return an *array* of all elements in the input array transformed using the 135 | input function. Your function should work like this: 136 | 137 | ```js 138 | function map(array, f) { 139 | // ... 140 | } 141 | map([1, 2, 3, 4], function(x) { 142 | return x * 2; 143 | }); 144 | // => [2, 4, 6, 8] 145 | ``` 146 | 147 | 6. Complete the invocations of `map` below to produce the desired output (you'll 148 | need to replace `???` with a function): 149 | 150 | ```js 151 | map(["hello", "world"], ???); // => ["HELLO", "WORLD"] 152 | map(["HelLo", "WorLD"], ???); // => ["hello", "world"] 153 | map(["the", "quick", "brown", "fox", "jumped"], ???); // => [3, 5, 5, 3, 6] 154 | var people = [ 155 | {name: "Alyssa P. Hacker", age: 26}, 156 | {name: "Ben Bitdiddle", age: 34}, 157 | {name: "Eva Lu Ator", age: 19}, 158 | {name: "Lem E. Tweakit", age: 40} 159 | ]; 160 | map(people, ???); // => ["Alyssa P. Hacker", "Ben Bitdiddle", "Eva Lu Ator", "Lem E. Tweakit"] 161 | map(people, ???); 162 | // => ["Alyssa P. Hacker is 26", "Ben Bitdiddle is 34", "Eva Lu Ator is 19", "Lem E. Tweakit is 40"] 163 | ``` 164 | 165 | #### Finding Patterns: Filtering 166 | 167 | 1. Write a function called `evens` that takes an array of **numbers** as a 168 | parameter, and returns **an array of only the even numbers** in the parameter. 169 | 170 | 2. Write a function called `multiplesOfThree` that takes an array of **numbers** as a 171 | parameter, and returns an array of only the numbers that are multiples of 172 | three. 173 | 174 | 3. Write a function called `positives` that takes an array of **numbers** as a parameter, and 175 | returns an array of only the numbers that are positive. 176 | 177 | 4. Write a function called `evenLength` that takes an array of **strings** and 178 | returns an array of only the strings with an even length. 179 | 180 | 5. At this point, you should notice a pattern; write a function called `filter` 181 | that takes two parameters: an array and a **function** that, when invoked with 182 | an argument, will return `true` or `false`. `filter` should return a *new 183 | array* of only the elements for which the function returns `true`: 184 | 185 | ```js 186 | function filter(array, f) { 187 | // ... 188 | } 189 | filter([1, 2, 3, 4], function(x) { 190 | return x % 2 === 0; // x is even? 191 | }); // => [2, 4] 192 | ``` 193 | 194 | 6. Use `filter` to write/rewrite: 195 | - `odds` 196 | - `positives` 197 | - `negatives` 198 | - `evenLength` 199 | - `largerThanSix` (given an array of numbers, returns those larger than 6) 200 | 201 | 7. Using `filter`, write a function `startsWithChar` that accepts two 202 | parameters: an array of strings, and a character (*e.g.* "a"), and returns an 203 | array of only the strings that start with that character: 204 | 205 | ```js 206 | function startsWithChar(strings, character) { 207 | // ... 208 | } 209 | var words = "the quick brown fox jumps over the lazy dog".split(" "); 210 | startsWithChar(words, "q"); // => ["quick"] 211 | startsWithChar(words, "t"); // => ["the", "the"] 212 | ``` 213 | -------------------------------------------------------------------------------- /3-scopes/README.md: -------------------------------------------------------------------------------- 1 | # Part III: Scopes 2 | 3 | *Note: Before getting started on these exercises, please be certain that you've read through the root [README.md](../README.md) file in this repository.* 4 | 5 | To complete these exercises, you will need to download this repo and open this particular folder in a code editor. 6 | 7 | ## Exercises 8 | 9 | #### It is your mission to go through the function.js file and change all the `'???'` in such a way that all the tests pass true. 10 | 11 | Run the specrunner.html file in a web browser. This document will immediately show one passed test and a series of failing tests. 12 | 13 | The **functions.js** file holds all the failing tests that are being displayed in **SpecRunner.html**. You will be editing the **functions.js** file and refreshing the **SpecRunner.html** to check your progress on making the tests pass. This is a regular JavaScript file, so note that you can use `console.log` to help debug and inspect these functions. 14 | 15 | A test block starts with an `it` function. The `it` function takes two arguments. The first one is a statement describing the rule addressed by the test. The second is a function that will either evaluate to true or false using the `expect` function. The expect statement (`expect(ACTUAL === 'inner').to.be.true;`) will evaluate if the statement between the parens `ACTUAL === 'inner'` is true. You can almost read it like plain English. The expect statement below "expects that the variable ACTUAL equals the value 'inner' to be true". 16 | 17 | #### Failing Test Example 18 | 19 | ```js 20 | it('a function has access to its own local scope variables', 21 | 22 | function () { 23 | var fn = function () { 24 | var name = 'inner'; 25 | ACTUAL = name; 26 | }; 27 | fn(); 28 | expect(ACTUAL === '???').to.be.true; 29 | // change '???' to what you believe ACTUAL will evaluate to. 30 | }); 31 | ``` 32 | 33 | #### Passing Test Example 34 | 35 | ```js 36 | it('a function has access to its own local scope variables', 37 | 38 | function () { 39 | var fn = function () { 40 | var name = 'inner'; 41 | ACTUAL = name; 42 | }; 43 | fn(); 44 | expect(ACTUAL === 'inner').to.be.true; 45 | // Here we changed '???' to 'inner' 46 | // (because we assigned ACTUAL, a global variable, to equal the value of name inside fn) 47 | }); 48 | ``` 49 | 50 | ### Don't forget.. 51 | 52 | You should thoroughly read all of code in front of you and aim to understand line-by-line what is happening. 53 | -------------------------------------------------------------------------------- /3-scopes/SpecRunner.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 | 5 |