diff --git a/1-hoisting/README.md b/1-hoisting/README.md new file mode 100644 index 0000000..7a0459d --- /dev/null +++ b/1-hoisting/README.md @@ -0,0 +1,176 @@ +# Part I: Hoisting (Solutions) + +### Two Forms of Functions + +```js +// function declaration +function square(x) { + return x * x; +} + +// function expression +var square = function(x) { + return x * x; +}; +``` + +## Exercises + +### Basic Requirements + +#### Rewrite Functions + +Rewrite the following *function declarations* using a *function expression*: + + ```js + // 1. + function cube(x) { + return x * x * x; + } + + // 2. + function fullName(first, last) { + return first + " " + last; + } + + // 3. + function power(base, exp) { + if (exp === 0) { + return 1; + } + return base * power(base, exp - 1); + } + + // 4. + function sumCubes(numbers) { + var total = 0; + for (var i = 0; i < numbers.length; i++) { + total = total + cube(numbers[i]); + } + return total; + } + ``` + +**FIXED:** + ```js + // 1. + var cube = function(x) { + return x * x * x; + } + + // 2. + var fullName = function(first, last) { + return first + " " + last; + } + + // 3. + var power = function(base, exp) { + if (exp === 0) { + return 1; + } + return base * power(base, exp - 1); + } + + // 4. + var sumCubes = function(numbers) { + var total = 0; + for (var i = 0; i < numbers.length; i++) { + total = total + cube(numbers[i]); + } + return total; + } + ``` + +#### Mechanics of Hoisting + +Type out your best answers to the following questions: + +1. Why does JavaScript output `undefined` instead of throwing an error in the following code? + + ```js + console.log(message); + + var message = 'Hi there!'; + ``` + + **ANSWER:** JavaScript's engine hoists the variable `message` prior to the `console.log()` invocation. At the time of hoisting, the variable `message` has a value of `undefined` until it is assigned a value of `Hi there!` immediately following the `console.log()` invocation. Since the variable exists at the time `console.log()` is invoked, there is no error message, but the value `undefined` is logged to the console. + +2. Why does JavaScript throw an error instead of logging `undefined` in the following code? + + ```js + console.log(message); + + let message = 'Hi there!'; + ``` + + **ANSWER:** JavaScript's ES6 version (released in 2015) came with two new keywords for declaring variables, `let` and `const`. These keywords can be leveraged in JavaScript for numerous purposes. One motivation for using `let` over `var` is that JavaScript will disallow a premature reference to a variable declared using `let`. In the above code, JavaScript's engine will throw an error instead of yielding `undefined` (as was demonstrated by the previous code in this section). + +3. Explain precisely what happens when the following code is executed. + + ```js + console.log(showMessage()); + + var showMessage = function(){ + return 'Hi there!'; + }; + ``` + **ANSWER:** JavaScript's engine will throw an error yielding that `showMessage` is not a function. This is a result of the hoisting of `showMessage`, which, at the time of its attempted invocation, maintains a value of `undefined`. JavaScript's engine doesn't recognize `undefined` as a function, and throws an error accordingly. + + +4. Why does JavaScript *not* throw any errors when the following code is executed? + + ```js + console.log(showMessage()); + + function showMessage(){ + return 'Hi there!'; + } + ``` + + **ANSWER:** JavaScript's engine hoists function declarations differently than it does variables. Variables are hoisted but their respective values aren't assigned until the interpreter reaches the line of code where the variable was defined at author-time. Function declarations behave similarly but also hoist the associated function value. This renders function declarations usable on the first line of code in any JavaScript program, irrespective of where it is defined at author-time. + +#### Code Restructuring + +Restructure the following instances of code to work correctly: + + ```js + // 1. + for(var i = 0; i < values.length; i++){ + console.log(values[i]); + } + + var values = [10, 20, 30]; + ``` + + **FIXED:** + ```js + // 1. + var values = [10, 20, 30]; + + for(var i = 0; i < values.length; i++){ + console.log(values[i]); + } + ``` + + ```js + // 2. + console.log(welcome('Charlie', 'Munger')); + + function welcome(first, last) { + return `Welcome, ${first} ${last}! You last logged in on ${lastLogin}.` + }; + + var lastLogin = '1/1/1970'; + ``` + + **FIXED:** + ```js + // 2. + var lastLogin = '1/1/1970'; + + console.log(welcome('Charlie', 'Munger')); + + function welcome(first, last) { + return `Welcome, ${first} ${last}! You last logged in on ${lastLogin}.` + }; + ``` diff --git a/3-higher-order-functions/README.md b/2-higher-order-functions/README.md similarity index 81% rename from 3-higher-order-functions/README.md rename to 2-higher-order-functions/README.md index acd683f..2c7c446 100644 --- a/3-higher-order-functions/README.md +++ b/2-higher-order-functions/README.md @@ -1,59 +1,9 @@ -# Part III: Higher-Order Functions - -*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.* - -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. - -### Two Forms of Functions - -```js -// function declaration -function square(x) { - return x * x; -} - -// function expression -var square = function(x) { - return x * x; -}; -``` +# Part II: Higher-Order Functions (Solutions) ## Exercises ### Basic Requirements -#### Rewrite Functions - -1. We have two ways of writing a function. The **function declaration** is what we've - used so far, and the **function expression** is new to us. Rewrite the following - *function declarations* using a *function expression*: - - ```js - // 1. - function cube(x) { - return x * x * x; - } - // 2. - function fullname(first, last) { - return first + " " + last; - } - // 3. - function power(base, exp) { - if (exp === 0) { - return 1; - } - return base * power(base, exp - 1); - } - // 4. - function sumCubes(numbers) { - var total = 0; - for (var i = 0; i < numbers.length; i++) { - total = total + cube(numbers[i]); - } - return total; - } - ``` - #### Iterating Over Arrays Using `each` 1. Write `each` as seen below in your code editor. @@ -76,6 +26,17 @@ var square = function(x) { } ``` + **SOLUTION:** + ```js + function sumSquares(numbers) { + var total = 0; + each(numbers, function(value){ + total = total + Math.pow(value, 2); + }); + return total; + } + ``` + 3. Rewrite `sumCubes` using `each`: ```js @@ -88,16 +49,81 @@ var square = function(x) { } ``` + **SOLUTION:** + ```js + function sumCubes(numbers) { + var total = 0; + each(numbers, function(value){ + total = total + cube(value); + }); + return total; + } + ``` + 3. Write a function called `product` that calculates the product of an array of numbers using a `for` loop; then, refactor it to use `each`. + **SOLUTION:** + ```js + // using a for() loop + function product(numbers){ + var total = 0; + for(var i = 0; i < numbers.length; i++){ + total = total * numbers[i]; + } + return total; + } + + // refactor using each() + function product(numbers){ + var total = 0; + each(numbers, function(value){ + total = total * value; + }); + return total; + } + ``` + 4. Write a function called `cubeAll` that cubes each number in an array, and returns an array of all the numbers *cubed* using a `for` loop; then, refactor it to use `each`. + **SOLUTION:** + ```js + // using a for() loop + function cubeAll(numbers){ + var cubedArr = []; + for(var i = 0; i < numbers.length; i++){ + cubedArr.push(cube(numbers[i])); + } + return cubedArr; + } + + // refactor using each() + function cubeAll(numbers){ + var cubedArr = []; + each(numbers, function(value){ + cubedArr.push(cube(value)); + }); + return cubedArr; + } + ``` + 5. Write a function called `odds` that accepts an array as a parameter and - returns an array of just the odd numbers. If you wrote it using `each`, - great! If you used anything else, refactor it to use a `for` loop. + returns an array of just the odd numbers. + + **SOLUTION:** + ```js + function odds(numbers) { + var oddsArr = []; + each(numbers, function(value){ + if(value % 2 !== 0){ + odds.push(value); + } + }); + return oddsArr; + } + ``` ### More Practice diff --git a/2-scopes/README.md b/2-scopes/README.md deleted file mode 100644 index cb3dcfd..0000000 --- a/2-scopes/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# Part II: Scopes - -*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.* - -To complete these exercises, you will need to download this repo and open this particular folder in a code editor. - -# How to complete these exercises - -#### 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. - -### Let's get started... - -Run the specrunner.html file in a web browser. This document will immediately show one passed test and a series of failing tests. - -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. - -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". - -#### Failing Test Example - - it('a function has access to its own local scope variables', - - function () { - var fn = function () { - var name = 'inner'; - ACTUAL = name; - }; - fn(); - expect(ACTUAL === '???').to.be.true; - //change '???' to what ACTUAL evaluates to. - }); - -#### Passing Test Example - - it('a function has access to its own local scope variables', - - function () { - var fn = function () { - var name = 'inner'; - ACTUAL = name; - }; - fn(); - expect(ACTUAL === 'inner').to.be.true; - //changed '???' to 'inner' - //(because we assigned ACTUAL, a global variable to name inside fn) - }); - -### Don't forget.. - -You should thoroughly read all of code in front of you and aim to understand line-by-line what is happening. diff --git a/3-scopes/README.md b/3-scopes/README.md new file mode 100644 index 0000000..6d89949 --- /dev/null +++ b/3-scopes/README.md @@ -0,0 +1,3 @@ +# Part III: Scopes (Solutions) + +Please see the `functions.js` file for the complete solution. diff --git a/3-scopes/SpecRunner.html b/3-scopes/SpecRunner.html new file mode 100755 index 0000000..6d98eb0 --- /dev/null +++ b/3-scopes/SpecRunner.html @@ -0,0 +1,21 @@ + +
+ + +