Feat: add new Markdown parser (#39800)

and change all the challenges to new `md` format.
This commit is contained in:
Oliver Eyton-Williams
2020-11-27 19:02:05 +01:00
committed by GitHub
parent a07f84c8ec
commit 0bd52f8bd1
2580 changed files with 113436 additions and 111979 deletions

View File

@ -5,10 +5,12 @@ challengeType: 1
forumTopicId: 301195
---
## Description
<section id='description'>
When you declare a variable with the <code>var</code> keyword, it is declared globally, or locally if declared inside a function.
The <code>let</code> keyword behaves similarly, but with some extra features. When you declare a variable with the <code>let</code> keyword inside a block, statement, or expression, its scope is limited to that block, statement, or expression.
# --description--
When you declare a variable with the `var` keyword, it is declared globally, or locally if declared inside a function.
The `let` keyword behaves similarly, but with some extra features. When you declare a variable with the `let` keyword inside a block, statement, or expression, its scope is limited to that block, statement, or expression.
For example:
```js
@ -22,7 +24,7 @@ console.log(i);
// returns 3
```
With the <code>var</code> keyword, <code>i</code> is declared globally. So when <code>i++</code> is executed, it updates the global variable. This code is similar to the following:
With the `var` keyword, `i` is declared globally. So when `i++` is executed, it updates the global variable. This code is similar to the following:
```js
var numArray = [];
@ -36,7 +38,7 @@ console.log(i);
// returns 3
```
This behavior will cause problems if you were to create a function and store it for later use inside a for loop that uses the <code>i</code> variable. This is because the stored function will always refer to the value of the updated global <code>i</code> variable.
This behavior will cause problems if you were to create a function and store it for later use inside a for loop that uses the `i` variable. This is because the stored function will always refer to the value of the updated global `i` variable.
```js
var printNumTwo;
@ -51,7 +53,7 @@ console.log(printNumTwo());
// returns 3
```
As you can see, <code>printNumTwo()</code> prints 3 and not 2. This is because the value assigned to <code>i</code> was updated and the <code>printNumTwo()</code> returns the global <code>i</code> and not the value <code>i</code> had when the function was created in the for loop. The <code>let</code> keyword does not follow this behavior:
As you can see, `printNumTwo()` prints 3 and not 2. This is because the value assigned to `i` was updated and the `printNumTwo()` returns the global `i` and not the value `i` had when the function was created in the for loop. The `let` keyword does not follow this behavior:
```js
let printNumTwo;
@ -68,35 +70,40 @@ console.log(i);
// returns "i is not defined"
```
<code>i</code> is not defined because it was not declared in the global scope. It is only declared within the for loop statement. <code>printNumTwo()</code> returned the correct value because three different <code>i</code> variables with unique values (0, 1, and 2) were created by the <code>let</code> keyword within the loop statement.
</section>
`i` is not defined because it was not declared in the global scope. It is only declared within the for loop statement. `printNumTwo()` returned the correct value because three different `i` variables with unique values (0, 1, and 2) were created by the `let` keyword within the loop statement.
## Instructions
<section id='instructions'>
Fix the code so that <code>i</code> declared in the if statement is a separate variable than <code>i</code> declared in the first line of the function. Be certain not to use the <code>var</code> keyword anywhere in your code.
This exercise is designed to illustrate the difference between how <code>var</code> and <code>let</code> keywords assign scope to the declared variable. When programming a function similar to the one used in this exercise, it is often better to use different variable names to avoid confusion.
</section>
# --instructions--
## Tests
<section id='tests'>
Fix the code so that `i` declared in the if statement is a separate variable than `i` declared in the first line of the function. Be certain not to use the `var` keyword anywhere in your code.
```yml
tests:
- text: <code>var</code> should not exist in code.
testString: getUserInput => assert(!getUserInput('index').match(/var/g));
- text: The variable <code>i</code> declared in the if statement should equal "block scope".
testString: getUserInput => assert(getUserInput('index').match(/(i\s*=\s*).*\s*.*\s*.*\1('|")block\s*scope\2/g));
- text: <code>checkScope()</code> should return "function scope"
testString: assert(checkScope() === "function scope");
This exercise is designed to illustrate the difference between how `var` and `let` keywords assign scope to the declared variable. When programming a function similar to the one used in this exercise, it is often better to use different variable names to avoid confusion.
# --hints--
`var` should not exist in code.
```js
(getUserInput) => assert(!getUserInput('index').match(/var/g));
```
</section>
The variable `i` declared in the if statement should equal "block scope".
## Challenge Seed
<section id='challengeSeed'>
```js
(getUserInput) =>
assert(
getUserInput('index').match(/(i\s*=\s*).*\s*.*\s*.*\1('|")block\s*scope\2/g)
);
```
<div id='js-seed'>
`checkScope()` should return "function scope"
```js
assert(checkScope() === 'function scope');
```
# --seed--
## --seed-contents--
```js
function checkScope() {
@ -110,14 +117,7 @@ function checkScope() {
}
```
</div>
</section>
## Solution
<section id='solution'>
# --solutions--
```js
function checkScope() {
@ -131,5 +131,3 @@ function checkScope() {
return i;
}
```
</section>

View File

@ -5,9 +5,9 @@ challengeType: 1
forumTopicId: 301196
---
## Description
<section id='description'>
A promise has three states: <code>pending</code>, <code>fulfilled</code>, and <code>rejected</code>. The promise you created in the last challenge is forever stuck in the <code>pending</code> state because you did not add a way to complete the promise. The <code>resolve</code> and <code>reject</code> parameters given to the promise argument are used to do this. <code>resolve</code> is used when you want your promise to succeed, and <code>reject</code> is used when you want it to fail. These are methods that take an argument, as seen below.
# --description--
A promise has three states: `pending`, `fulfilled`, and `rejected`. The promise you created in the last challenge is forever stuck in the `pending` state because you did not add a way to complete the promise. The `resolve` and `reject` parameters given to the promise argument are used to do this. `resolve` is used when you want your promise to succeed, and `reject` is used when you want it to fail. These are methods that take an argument, as seen below.
```js
const myPromise = new Promise((resolve, reject) => {
@ -20,50 +20,55 @@ const myPromise = new Promise((resolve, reject) => {
```
The example above uses strings for the argument of these functions, but it can really be anything. Often, it might be an object, that you would use data from, to put on your website or elsewhere.
</section>
## Instructions
<section id='instructions'>
Make the promise handle success and failure. If <code>responseFromServer</code> is <code>true</code>, call the <code>resolve</code> method to successfully complete the promise. Pass <code>resolve</code> a string with the value <code>We got the data</code>. If <code>responseFromServer</code> is <code>false</code>, use the <code>reject</code> method instead and pass it the string: <code>Data not received</code>.
</section>
# --instructions--
## Tests
<section id='tests'>
Make the promise handle success and failure. If `responseFromServer` is `true`, call the `resolve` method to successfully complete the promise. Pass `resolve` a string with the value `We got the data`. If `responseFromServer` is `false`, use the `reject` method instead and pass it the string: `Data not received`.
```yml
tests:
- text: <code>resolve</code> should be called with the expected string when the <code>if</code> condition is <code>true</code>.
testString: assert(__helpers.removeJSComments(code).match(/if\s*\(\s*responseFromServer\s*\)\s*{\s*resolve\s*\(\s*('|"|`)We got the data\1\s*\)(\s*|\s*;\s*)}/g));
- text: <code>reject</code> should be called with the expected string when the <code>if</code> condition is <code>false</code>.
testString: assert(__helpers.removeJSComments(code).match(/}\s*else\s*{\s*reject\s*\(\s*('|"|`)Data not received\1\s*\)(\s*|\s*;\s*)}/g));
# --hints--
`resolve` should be called with the expected string when the `if` condition is `true`.
```js
assert(
__helpers
.removeJSComments(code)
.match(
/if\s*\(\s*responseFromServer\s*\)\s*{\s*resolve\s*\(\s*('|"|`)We got the data\1\s*\)(\s*|\s*;\s*)}/g
)
);
```
</section>
`reject` should be called with the expected string when the `if` condition is `false`.
## Challenge Seed
<section id='challengeSeed'>
<div id='js-seed'>
```js
assert(
__helpers
.removeJSComments(code)
.match(
/}\s*else\s*{\s*reject\s*\(\s*('|"|`)Data not received\1\s*\)(\s*|\s*;\s*)}/g
)
);
```
# --seed--
## --seed-contents--
```js
const makeServerRequest = new Promise((resolve, reject) => {
// responseFromServer represents a response from a server
let responseFromServer;
if(responseFromServer) {
// Change this line
} else {
} else {
// Change this line
}
});
```
</div>
</section>
## Solution
<section id='solution'>
# --solutions--
```js
const makeServerRequest = new Promise((resolve, reject) => {
@ -72,10 +77,8 @@ const makeServerRequest = new Promise((resolve, reject) => {
if(responseFromServer) {
resolve("We got the data");
} else {
} else {
reject("Data not received");
}
});
```
</section>

View File

@ -5,9 +5,9 @@ challengeType: 1
forumTopicId: 301197
---
## Description
<section id='description'>
A promise in JavaScript is exactly what it sounds like - you use it to make a promise to do something, usually asynchronously. When the task completes, you either fulfill your promise or fail to do so. <code>Promise</code> is a constructor function, so you need to use the <code>new</code> keyword to create one. It takes a function, as its argument, with two parameters - <code>resolve</code> and <code>reject</code>. These are methods used to determine the outcome of the promise. The syntax looks like this:
# --description--
A promise in JavaScript is exactly what it sounds like - you use it to make a promise to do something, usually asynchronously. When the task completes, you either fulfill your promise or fail to do so. `Promise` is a constructor function, so you need to use the `new` keyword to create one. It takes a function, as its argument, with two parameters - `resolve` and `reject`. These are methods used to determine the outcome of the promise. The syntax looks like this:
```js
const myPromise = new Promise((resolve, reject) => {
@ -15,44 +15,39 @@ const myPromise = new Promise((resolve, reject) => {
});
```
</section>
# --instructions--
## Instructions
<section id='instructions'>
Create a new promise called <code>makeServerRequest</code>. Pass in a function with <code>resolve</code> and <code>reject</code> parameters to the constructor.
</section>
Create a new promise called `makeServerRequest`. Pass in a function with `resolve` and `reject` parameters to the constructor.
## Tests
<section id='tests'>
# --hints--
```yml
tests:
- text: You should assign a promise to a declared variable named <code>makeServerRequest</code>.
testString: assert(makeServerRequest instanceof Promise);
- text: Your promise should receive a function with <code>resolve</code> and <code>reject</code> as parameters.
testString: assert(code.match(/Promise\(\s*(function\s*\(\s*resolve\s*,\s*reject\s*\)\s*{|\(\s*resolve\s*,\s*reject\s*\)\s*=>\s*{)[^}]*}/g));
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='js-seed'>
You should assign a promise to a declared variable named `makeServerRequest`.
```js
assert(makeServerRequest instanceof Promise);
```
</div>
</section>
Your promise should receive a function with `resolve` and `reject` as parameters.
## Solution
<section id='solution'>
```js
assert(
code.match(
/Promise\(\s*(function\s*\(\s*resolve\s*,\s*reject\s*\)\s*{|\(\s*resolve\s*,\s*reject\s*\)\s*=>\s*{)[^}]*}/g
)
);
```
# --seed--
## --seed-contents--
```js
```
# --solutions--
```js
const makeServerRequest = new Promise((resolve, reject) => {
});
```
</section>

View File

@ -5,40 +5,51 @@ challengeType: 6
forumTopicId: 301198
---
## Description
<section id='description'>
JavaScript started with a small role to play on an otherwise mostly HTML web. Today, its huge, and some websites are built almost entirely with JavaScript. In order to make JavaScript more modular, clean, and maintainable; ES6 introduced a way to easily share code among JavaScript files. This involves exporting parts of a file for use in one or more other files, and importing the parts you need, where you need them. In order to take advantage of this functionality, you need to create a script in your HTML document with a type of <code>module</code>. Heres an example:
# --description--
JavaScript started with a small role to play on an otherwise mostly HTML web. Today, its huge, and some websites are built almost entirely with JavaScript. In order to make JavaScript more modular, clean, and maintainable; ES6 introduced a way to easily share code among JavaScript files. This involves exporting parts of a file for use in one or more other files, and importing the parts you need, where you need them. In order to take advantage of this functionality, you need to create a script in your HTML document with a type of `module`. Heres an example:
```html
<script type="module" src="filename.js"></script>
```
A script that uses this <code>module</code> type can now use the <code>import</code> and <code>export</code> features you will learn about in the upcoming challenges.
</section>
A script that uses this `module` type can now use the `import` and `export` features you will learn about in the upcoming challenges.
## Instructions
<section id='instructions'>
Add a script to the HTML document of type <code>module</code> and give it the source file of <code>index.js</code>
</section>
# --instructions--
## Tests
<section id='tests'>
Add a script to the HTML document of type `module` and give it the source file of `index.js`
```yml
tests:
- text: You should create a <code>script</code> tag.
testString: assert(code.match(/<\s*script[^>]*>\s*<\/\s*script\s*>/g));
- text: Your <code>script</code> tag should be of type <code>module</code>.
testString: assert(code.match(/<\s*script\s+[^t]*type\s*=\s*('|")module\1[^>]*>\s*<\/\s*script\s*>/g));
- text: Your <code>script</code> tag should have a <code>src</code> of <code>index.js</code>.
testString: assert(code.match(/<\s*script\s+[^s]*src\s*=\s*('|")index\.js\1[^>]*>\s*<\/\s*script\s*>/g));
# --hints--
You should create a `script` tag.
```js
assert(code.match(/<\s*script[^>]*>\s*<\/\s*script\s*>/g));
```
</section>
Your `script` tag should be of type `module`.
## Challenge Seed
<section id='challengeSeed'>
<div id='html-seed'>
```js
assert(
code.match(
/<\s*script\s+[^t]*type\s*=\s*('|")module\1[^>]*>\s*<\/\s*script\s*>/g
)
);
```
Your `script` tag should have a `src` of `index.js`.
```js
assert(
code.match(
/<\s*script\s+[^s]*src\s*=\s*('|")index\.js\1[^>]*>\s*<\/\s*script\s*>/g
)
);
```
# --seed--
## --seed-contents--
```html
<html>
@ -50,11 +61,7 @@ tests:
</html>
```
</div>
</section>
## Solution
<section id='solution'>
# --solutions--
```html
<html>
@ -63,5 +70,3 @@ tests:
</body>
</html>
```
</section>

View File

@ -5,11 +5,13 @@ challengeType: 1
forumTopicId: 301199
---
## Description
<section id='description'>
In the <code>export</code> lesson, you learned about the syntax referred to as a <dfn>named export</dfn>. This allowed you to make multiple functions and variables available for use in other files.
There is another <code>export</code> syntax you need to know, known as <dfn>export default</dfn>. Usually you will use this syntax if only one value is being exported from a file. It is also used to create a fallback value for a file or module.
Below are examples using <code>export default</code>:
# --description--
In the `export` lesson, you learned about the syntax referred to as a <dfn>named export</dfn>. This allowed you to make multiple functions and variables available for use in other files.
There is another `export` syntax you need to know, known as <dfn>export default</dfn>. Usually you will use this syntax if only one value is being exported from a file. It is also used to create a fallback value for a file or module.
Below are examples using `export default`:
```js
// named function
@ -23,28 +25,27 @@ export default function(x, y) {
}
```
Since <code>export default</code> is used to declare a fallback value for a module or file, you can only have one value be a default export in each module or file. Additionally, you cannot use <code>export default</code> with <code>var</code>, <code>let</code>, or <code>const</code>
</section>
Since `export default` is used to declare a fallback value for a module or file, you can only have one value be a default export in each module or file. Additionally, you cannot use `export default` with `var`, `let`, or `const`
# --instructions--
## Instructions
<section id='instructions'>
The following function should be the fallback value for the module. Please add the necessary code to do so.
</section>
## Tests
<section id='tests'>
# --hints--
```yml
tests:
- text: Your code should use <code>export</code> fallback.
testString: assert(code.match(/export\s+default\s+function(\s+subtract\s*|\s*)\(\s*x,\s*y\s*\)\s*{/g));
Your code should use `export` fallback.
```js
assert(
code.match(
/export\s+default\s+function(\s+subtract\s*|\s*)\(\s*x,\s*y\s*\)\s*{/g
)
);
```
</section>
# --seed--
## Challenge Seed
<section id='challengeSeed'>
<div id='js-seed'>
## --seed-contents--
```js
function subtract(x, y) {
@ -52,16 +53,10 @@ function subtract(x, y) {
}
```
</div>
</section>
## Solution
<section id='solution'>
# --solutions--
```js
export default function subtract(x, y) {
return x - y;
}
```
</section>

View File

@ -5,10 +5,12 @@ challengeType: 1
forumTopicId: 301200
---
## Description
<section id='description'>
# --description--
A new feature of ES6 is the <dfn>template literal</dfn>. This is a special type of string that makes creating complex strings easier.
Template literals allow you to create multi-line strings and to use string interpolation features to create strings.
Consider the code below:
```js
@ -27,16 +29,12 @@ console.log(greeting); // prints
```
A lot of things happened there.
Firstly, the example uses backticks (<code>`</code>), not quotes (<code>'</code> or <code>"</code>), to wrap the string.
Secondly, notice that the string is multi-line, both in the code and the output. This saves inserting <code>\n</code> within strings.
The <code>${variable}</code> syntax used above is a placeholder. Basically, you won't have to use concatenation with the <code>+</code> operator anymore. To add variables to strings, you just drop the variable in a template string and wrap it with <code>${</code> and <code>}</code>. Similarly, you can include other expressions in your string literal, for example <code>${a + b}</code>.
This new way of creating strings gives you more flexibility to create robust strings.
</section>
A lot of things happened there. Firstly, the example uses backticks (`` ` ``), not quotes (`'` or `"`), to wrap the string. Secondly, notice that the string is multi-line, both in the code and the output. This saves inserting `\n` within strings. The `${variable}` syntax used above is a placeholder. Basically, you won't have to use concatenation with the `+` operator anymore. To add variables to strings, you just drop the variable in a template string and wrap it with `${` and `}`. Similarly, you can include other expressions in your string literal, for example `${a + b}`. This new way of creating strings gives you more flexibility to create robust strings.
# --instructions--
Use template literal syntax with backticks to create an array of list element (`li`) strings. Each list element's text should be one of the array elements from the `failure` property on the `result` object and have a `class` attribute with the value `text-warning`. The `makeList` function should return the array of list item strings.
## Instructions
<section id='instructions'>
Use template literal syntax with backticks to create an array of list element (<code>li</code>) strings. Each list element's text should be one of the array elements from the <code>failure</code> property on the <code>result</code> object and have a <code>class</code> attribute with the value <code>text-warning</code>. The <code>makeList</code> function should return the array of list item strings.
Use an iterator method (any kind of loop) to get the desired output (shown below).
```js
@ -47,29 +45,44 @@ Use an iterator method (any kind of loop) to get the desired output (shown below
]
```
</section>
# --hints--
## Tests
<section id='tests'>
`failuresList` should be an array containing `result failure` messages.
```yml
tests:
- text: <code>failuresList</code> should be an array containing <code>result failure</code> messages.
testString: assert(typeof makeList(result.failure) === 'object' && failuresList.length === 3);
- text: <code>failuresList</code> should be equal to the specified output.
testString: assert(makeList(result.failure).every((v, i) => v === `<li class="text-warning">${result.failure[i]}</li>` || v === `<li class='text-warning'>${result.failure[i]}</li>`));
- text: Template strings and expression interpolation should be used.
testString: getUserInput => assert(getUserInput('index').match(/(`.*\${.*}.*`)/));
- text: An iterator should be used.
testString: getUserInput => assert(getUserInput('index').match(/for|map|reduce|forEach|while/));
```js
assert(
typeof makeList(result.failure) === 'object' && failuresList.length === 3
);
```
</section>
`failuresList` should be equal to the specified output.
## Challenge Seed
<section id='challengeSeed'>
```js
assert(
makeList(result.failure).every(
(v, i) =>
v === `<li class="text-warning">${result.failure[i]}</li>` ||
v === `<li class='text-warning'>${result.failure[i]}</li>`
)
);
```
<div id='js-seed'>
Template strings and expression interpolation should be used.
```js
(getUserInput) => assert(getUserInput('index').match(/(`.*\${.*}.*`)/));
```
An iterator should be used.
```js
(getUserInput) =>
assert(getUserInput('index').match(/for|map|reduce|forEach|while/));
```
# --seed--
## --seed-contents--
```js
const result = {
@ -88,14 +101,7 @@ function makeList(arr) {
const failuresList = makeList(result.failure);
```
</div>
</section>
## Solution
<section id='solution'>
# --solutions--
```js
const result = {
@ -109,5 +115,3 @@ function makeList(arr) {
const failuresList = makeList(result.failure);
```
</section>

View File

@ -5,48 +5,55 @@ challengeType: 1
forumTopicId: 301201
---
## Description
<section id='description'>
The keyword <code>let</code> is not the only new way to declare variables. In ES6, you can also declare variables using the <code>const</code> keyword.
<code>const</code> has all the awesome features that <code>let</code> has, with the added bonus that variables declared using <code>const</code> are read-only. They are a constant value, which means that once a variable is assigned with <code>const</code>, it cannot be reassigned.
# --description--
The keyword `let` is not the only new way to declare variables. In ES6, you can also declare variables using the `const` keyword.
`const` has all the awesome features that `let` has, with the added bonus that variables declared using `const` are read-only. They are a constant value, which means that once a variable is assigned with `const`, it cannot be reassigned.
```js
const FAV_PET = "Cats";
FAV_PET = "Dogs"; // returns error
```
As you can see, trying to reassign a variable declared with <code>const</code> will throw an error. You should always name variables you don't want to reassign using the <code>const</code> keyword. This helps when you accidentally attempt to reassign a variable that is meant to stay constant. A common practice when naming constants is to use all uppercase letters, with words separated by an underscore.
<strong>Note:</strong> It is common for developers to use uppercase variable identifiers for immutable values and lowercase or camelCase for mutable values (objects and arrays). In a later challenge you will see an example of a lowercase variable identifier being used for an array.
</section>
As you can see, trying to reassign a variable declared with `const` will throw an error. You should always name variables you don't want to reassign using the `const` keyword. This helps when you accidentally attempt to reassign a variable that is meant to stay constant. A common practice when naming constants is to use all uppercase letters, with words separated by an underscore.
## Instructions
<section id='instructions'>
Change the code so that all variables are declared using <code>let</code> or <code>const</code>. Use <code>let</code> when you want the variable to change, and <code>const</code> when you want the variable to remain constant. Also, rename variables declared with <code>const</code> to conform to common practices, meaning constants should be in all caps.
</section>
**Note:** It is common for developers to use uppercase variable identifiers for immutable values and lowercase or camelCase for mutable values (objects and arrays). In a later challenge you will see an example of a lowercase variable identifier being used for an array.
## Tests
<section id='tests'>
# --instructions--
```yml
tests:
- text: <code>var</code> should not exist in your code.
testString: getUserInput => assert(!getUserInput('index').match(/var/g));
- text: <code>SENTENCE</code> should be a constant variable declared with <code>const</code>.
testString: getUserInput => assert(getUserInput('index').match(/(const SENTENCE)/g));
- text: <code>i</code> should be declared with <code>let</code>.
testString: getUserInput => assert(getUserInput('index').match(/(let i)/g));
- text: <code>console.log</code> should be changed to print the <code>SENTENCE</code> variable.
testString: getUserInput => assert(getUserInput('index').match(/console\.log\(\s*SENTENCE\s*\)\s*;?/g));
Change the code so that all variables are declared using `let` or `const`. Use `let` when you want the variable to change, and `const` when you want the variable to remain constant. Also, rename variables declared with `const` to conform to common practices, meaning constants should be in all caps.
# --hints--
`var` should not exist in your code.
```js
(getUserInput) => assert(!getUserInput('index').match(/var/g));
```
</section>
`SENTENCE` should be a constant variable declared with `const`.
## Challenge Seed
<section id='challengeSeed'>
```js
(getUserInput) => assert(getUserInput('index').match(/(const SENTENCE)/g));
```
<div id='js-seed'>
`i` should be declared with `let`.
```js
(getUserInput) => assert(getUserInput('index').match(/(let i)/g));
```
`console.log` should be changed to print the `SENTENCE` variable.
```js
(getUserInput) =>
assert(getUserInput('index').match(/console\.log\(\s*SENTENCE\s*\)\s*;?/g));
```
# --seed--
## --seed-contents--
```js
function printManyTimes(str) {
@ -64,14 +71,7 @@ function printManyTimes(str) {
printManyTimes("freeCodeCamp");
```
</div>
</section>
## Solution
<section id='solution'>
# --solutions--
```js
function printManyTimes(str) {
@ -84,5 +84,3 @@ function printManyTimes(str) {
}
printManyTimes("freeCodeCamp");
```
</section>

View File

@ -5,9 +5,9 @@ challengeType: 1
forumTopicId: 301202
---
## Description
<section id='description'>
One of the biggest problems with declaring variables with the <code>var</code> keyword is that you can overwrite variable declarations without an error.
# --description--
One of the biggest problems with declaring variables with the `var` keyword is that you can overwrite variable declarations without an error.
```js
var camper = 'James';
@ -16,53 +16,48 @@ console.log(camper);
// logs 'David'
```
As you can see in the code above, the <code>camper</code> variable is originally declared as <code>James</code> and then overridden to be <code>David</code>.
In a small application, you might not run into this type of problem, but when your code becomes larger, you might accidentally overwrite a variable that you did not intend to overwrite.
Because this behavior does not throw an error, searching and fixing bugs becomes more difficult.<br>
A new keyword called <code>let</code> was introduced in ES6 to solve this potential issue with the <code>var</code> keyword.
If you were to replace <code>var</code> with <code>let</code> in the variable declarations of the code above, the result would be an error.
As you can see in the code above, the `camper` variable is originally declared as `James` and then overridden to be `David`. In a small application, you might not run into this type of problem, but when your code becomes larger, you might accidentally overwrite a variable that you did not intend to overwrite. Because this behavior does not throw an error, searching and fixing bugs becomes more difficult.
A new keyword called `let` was introduced in ES6 to solve this potential issue with the `var` keyword. If you were to replace `var` with `let` in the variable declarations of the code above, the result would be an error.
```js
let camper = 'James';
let camper = 'David'; // throws an error
```
This error can be seen in the console of your browser.
So unlike <code>var</code>, when using <code>let</code>, a variable with the same name can only be declared once.
Note the <code>"use strict"</code>. This enables Strict Mode, which catches common coding mistakes and "unsafe" actions. For instance:
This error can be seen in the console of your browser. So unlike `var`, when using `let`, a variable with the same name can only be declared once. Note the `"use strict"`. This enables Strict Mode, which catches common coding mistakes and "unsafe" actions. For instance:
```js
"use strict";
x = 3.14; // throws an error because x is not declared
```
</section>
# --instructions--
## Instructions
<section id='instructions'>
Update the code so it only uses the <code>let</code> keyword.
</section>
Update the code so it only uses the `let` keyword.
## Tests
<section id='tests'>
# --hints--
```yml
tests:
- text: <code>var</code> should not exist in the code.
testString: getUserInput => assert(!getUserInput('index').match(/var/g));
- text: <code>catName</code> should be <code>Oliver</code>.
testString: assert(catName === "Oliver");
- text: <code>quote</code> should be <code>"Oliver says Meow!"</code>
testString: assert(quote === "Oliver says Meow!");
`var` should not exist in the code.
```js
(getUserInput) => assert(!getUserInput('index').match(/var/g));
```
</section>
`catName` should be `Oliver`.
## Challenge Seed
<section id='challengeSeed'>
```js
assert(catName === 'Oliver');
```
<div id='js-seed'>
`quote` should be `"Oliver says Meow!"`
```js
assert(quote === 'Oliver says Meow!');
```
# --seed--
## --seed-contents--
```js
var catName;
@ -77,14 +72,7 @@ function catTalk() {
catTalk();
```
</div>
</section>
## Solution
<section id='solution'>
# --solutions--
```js
let catName;
@ -97,5 +85,3 @@ function catTalk() {
}
catTalk();
```
</section>

View File

@ -5,9 +5,9 @@ challengeType: 1
forumTopicId: 301203
---
## Description
<section id='description'>
Promises are most useful when you have a process that takes an unknown amount of time in your code (i.e. something asynchronous), often a server request. When you make a server request it takes some amount of time, and after it completes you usually want to do something with the response from the server. This can be achieved by using the <code>then</code> method. The <code>then</code> method is executed immediately after your promise is fulfilled with <code>resolve</code>. Heres an example:
# --description--
Promises are most useful when you have a process that takes an unknown amount of time in your code (i.e. something asynchronous), often a server request. When you make a server request it takes some amount of time, and after it completes you usually want to do something with the response from the server. This can be achieved by using the `then` method. The `then` method is executed immediately after your promise is fulfilled with `resolve`. Heres an example:
```js
myPromise.then(result => {
@ -15,69 +15,72 @@ myPromise.then(result => {
});
```
<code>result</code> comes from the argument given to the <code>resolve</code> method.
</section>
`result` comes from the argument given to the `resolve` method.
## Instructions
<section id='instructions'>
Add the <code>then</code> method to your promise. Use <code>result</code> as the parameter of its callback function and log <code>result</code> to the console.
</section>
# --instructions--
## Tests
<section id='tests'>
Add the `then` method to your promise. Use `result` as the parameter of its callback function and log `result` to the console.
```yml
tests:
- text: You should call the <code>then</code> method on the promise.
testString: assert(__helpers.removeWhiteSpace(code).match(/(makeServerRequest|\))\.then\(/g));
- text: Your <code>then</code> method should have a callback function with <code>result</code> as its parameter.
testString: assert(resultIsParameter);
- text: You should log <code>result</code> to the console.
testString: assert(resultIsParameter && __helpers.removeWhiteSpace(code).match(/\.then\(.*?result.*?console.log\(result\).*?\)/));
```
# --hints--
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='js-seed'>
You should call the `then` method on the promise.
```js
const makeServerRequest = new Promise((resolve, reject) => {
// responseFromServer is set to true to represent a successful response from a server
let responseFromServer = true;
if(responseFromServer) {
resolve("We got the data");
} else {
reject("Data not received");
}
});
assert(
__helpers.removeWhiteSpace(code).match(/(makeServerRequest|\))\.then\(/g)
);
```
</div>
Your `then` method should have a callback function with `result` as its parameter.
### After Test
<div id='js-teardown'>
```js
assert(resultIsParameter);
```
You should log `result` to the console.
```js
assert(
resultIsParameter &&
__helpers
.removeWhiteSpace(code)
.match(/\.then\(.*?result.*?console.log\(result\).*?\)/)
);
```
# --seed--
## --after-user-code--
```js
const resultIsParameter = /\.then\((function\(result\){|result|\(result\)=>)/.test(__helpers.removeWhiteSpace(code));
```
</div>
</section>
## Solution
<section id='solution'>
## --seed-contents--
```js
const makeServerRequest = new Promise((resolve, reject) => {
// responseFromServer is set to true to represent a successful response from a server
let responseFromServer = true;
if(responseFromServer) {
resolve("We got the data");
} else {
} else {
reject("Data not received");
}
});
```
# --solutions--
```js
const makeServerRequest = new Promise((resolve, reject) => {
// responseFromServer is set to true to represent a successful response from a server
let responseFromServer = true;
if(responseFromServer) {
resolve("We got the data");
} else {
reject("Data not received");
}
});
@ -86,5 +89,3 @@ makeServerRequest.then(result => {
console.log(result);
});
```
</section>

View File

@ -5,9 +5,9 @@ challengeType: 1
forumTopicId: 301204
---
## Description
<section id='description'>
<code>catch</code> is the method used when your promise has been rejected. It is executed immediately after a promise's <code>reject</code> method is called. Heres the syntax:
# --description--
`catch` is the method used when your promise has been rejected. It is executed immediately after a promise's `reject` method is called. Heres the syntax:
```js
myPromise.catch(error => {
@ -15,41 +15,57 @@ myPromise.catch(error => {
});
```
<code>error</code> is the argument passed in to the <code>reject</code> method.
</section>
`error` is the argument passed in to the `reject` method.
## Instructions
<section id='instructions'>
Add the <code>catch</code> method to your promise. Use <code>error</code> as the parameter of its callback function and log <code>error</code> to the console.
</section>
# --instructions--
## Tests
<section id='tests'>
Add the `catch` method to your promise. Use `error` as the parameter of its callback function and log `error` to the console.
```yml
tests:
- text: You should call the <code>catch</code> method on the promise.
testString: assert(__helpers.removeWhiteSpace(code).match(/(makeServerRequest|\))\.catch\(/g));
- text: Your <code>catch</code> method should have a callback function with <code>error</code> as its parameter.
testString: assert(errorIsParameter);
- text: You should log <code>error</code> to the console.
testString: assert(errorIsParameter && __helpers.removeWhiteSpace(code).match(/\.catch\(.*?error.*?console.log\(error\).*?\)/));
# --hints--
You should call the `catch` method on the promise.
```js
assert(
__helpers.removeWhiteSpace(code).match(/(makeServerRequest|\))\.catch\(/g)
);
```
</section>
Your `catch` method should have a callback function with `error` as its parameter.
## Challenge Seed
<section id='challengeSeed'>
<div id='js-seed'>
```js
assert(errorIsParameter);
```
You should log `error` to the console.
```js
assert(
errorIsParameter &&
__helpers
.removeWhiteSpace(code)
.match(/\.catch\(.*?error.*?console.log\(error\).*?\)/)
);
```
# --seed--
## --after-user-code--
```js
const errorIsParameter = /\.catch\((function\(error\){|error|\(error\)=>)/.test(__helpers.removeWhiteSpace(code));
```
## --seed-contents--
```js
const makeServerRequest = new Promise((resolve, reject) => {
// responseFromServer is set to false to represent an unsuccessful response from a server
let responseFromServer = false;
if(responseFromServer) {
resolve("We got the data");
} else {
} else {
reject("Data not received");
}
});
@ -59,30 +75,16 @@ makeServerRequest.then(result => {
});
```
</div>
### After Test
<div id='js-teardown'>
```js
const errorIsParameter = /\.catch\((function\(error\){|error|\(error\)=>)/.test(__helpers.removeWhiteSpace(code));
```
</div>
</section>
## Solution
<section id='solution'>
# --solutions--
```js
const makeServerRequest = new Promise((resolve, reject) => {
// responseFromServer is set to false to represent an unsuccessful response from a server
let responseFromServer = false;
if(responseFromServer) {
resolve("We got the data");
} else {
} else {
reject("Data not received");
}
});
@ -95,5 +97,3 @@ makeServerRequest.catch(error => {
console.log(error);
});
```
</section>

View File

@ -5,36 +5,31 @@ challengeType: 1
forumTopicId: 301205
---
## Description
<section id='description'>
In the last challenge, you learned about <code>export default</code> and its uses. To import a default export, you need to use a different <code>import</code> syntax. In the following example, <code>add</code> is the default export of the <code>math_functions.js</code> file. Here is how to import it:
# --description--
In the last challenge, you learned about `export default` and its uses. To import a default export, you need to use a different `import` syntax. In the following example, `add` is the default export of the `math_functions.js` file. Here is how to import it:
```js
import add from "./math_functions.js";
```
The syntax differs in one key place. The imported value, <code>add</code>, is not surrounded by curly braces (<code>{}</code>). <code>add</code> here is simply a variable name for whatever the default export of the <code>math_functions.js</code> file is. You can use any name here when importing a default.
</section>
The syntax differs in one key place. The imported value, `add`, is not surrounded by curly braces (`{}`). `add` here is simply a variable name for whatever the default export of the `math_functions.js` file is. You can use any name here when importing a default.
## Instructions
<section id='instructions'>
In the following code, import the default export from the <code>math_functions.js</code> file, found in the same directory as this file. Give the import the name <code>subtract</code>.
</section>
# --instructions--
## Tests
<section id='tests'>
In the following code, import the default export from the `math_functions.js` file, found in the same directory as this file. Give the import the name `subtract`.
```yml
tests:
- text: You should properly import <code>subtract</code> from <code>math_functions.js</code>.
testString: assert(code.match(/import\s+subtract\s+from\s+('|")\.\/math_functions\.js\1/g));
# --hints--
You should properly import `subtract` from `math_functions.js`.
```js
assert(code.match(/import\s+subtract\s+from\s+('|")\.\/math_functions\.js\1/g));
```
</section>
# --seed--
## Challenge Seed
<section id='challengeSeed'>
<div id='js-seed'>
## --seed-contents--
```js
@ -43,16 +38,10 @@ tests:
subtract(7,4);
```
</div>
</section>
## Solution
<section id='solution'>
# --solutions--
```js
import subtract from "./math_functions.js";
subtract(7,4);
```
</section>

View File

@ -5,11 +5,13 @@ challengeType: 1
forumTopicId: 301206
---
## Description
<section id='description'>
The <code>const</code> declaration has many use cases in modern JavaScript.
Some developers prefer to assign all their variables using <code>const</code> by default, unless they know they will need to reassign the value. Only in that case, they use <code>let</code>.
However, it is important to understand that objects (including arrays and functions) assigned to a variable using <code>const</code> are still mutable. Using the <code>const</code> declaration only prevents reassignment of the variable identifier.
# --description--
The `const` declaration has many use cases in modern JavaScript.
Some developers prefer to assign all their variables using `const` by default, unless they know they will need to reassign the value. Only in that case, they use `let`.
However, it is important to understand that objects (including arrays and functions) assigned to a variable using `const` are still mutable. Using the `const` declaration only prevents reassignment of the variable identifier.
```js
const s = [5, 6, 7];
@ -18,36 +20,46 @@ s[2] = 45; // works just as it would with an array declared with var or let
console.log(s); // returns [5, 6, 45]
```
As you can see, you can mutate the object <code>[5, 6, 7]</code> itself and the variable <code>s</code> will still point to the altered array <code>[5, 6, 45]</code>. Like all arrays, the array elements in <code>s</code> are mutable, but because <code>const</code> was used, you cannot use the variable identifier <code>s</code> to point to a different array using the assignment operator.
</section>
As you can see, you can mutate the object `[5, 6, 7]` itself and the variable `s` will still point to the altered array `[5, 6, 45]`. Like all arrays, the array elements in `s` are mutable, but because `const` was used, you cannot use the variable identifier `s` to point to a different array using the assignment operator.
## Instructions
<section id='instructions'>
An array is declared as <code>const s = [5, 7, 2]</code>. Change the array to <code>[2, 5, 7]</code> using various element assignments.
</section>
# --instructions--
## Tests
<section id='tests'>
An array is declared as `const s = [5, 7, 2]`. Change the array to `[2, 5, 7]` using various element assignments.
```yml
tests:
- text: You should not replace <code>const</code> keyword.
testString: getUserInput => assert(getUserInput('index').match(/const/g));
- text: <code>s</code> should be a constant variable (by using <code>const</code>).
testString: getUserInput => assert(getUserInput('index').match(/const\s+s/g));
- text: You should not change the original array declaration.
testString: getUserInput => assert(getUserInput('index').match(/const\s+s\s*=\s*\[\s*5\s*,\s*7\s*,\s*2\s*\]\s*;?/g));
- text: <code>s</code> should be equal to <code>[2, 5, 7]</code>.
testString: assert.deepEqual(s, [2, 5, 7]);
# --hints--
You should not replace `const` keyword.
```js
(getUserInput) => assert(getUserInput('index').match(/const/g));
```
</section>
`s` should be a constant variable (by using `const`).
## Challenge Seed
<section id='challengeSeed'>
```js
(getUserInput) => assert(getUserInput('index').match(/const\s+s/g));
```
<div id='js-seed'>
You should not change the original array declaration.
```js
(getUserInput) =>
assert(
getUserInput('index').match(
/const\s+s\s*=\s*\[\s*5\s*,\s*7\s*,\s*2\s*\]\s*;?/g
)
);
```
`s` should be equal to `[2, 5, 7]`.
```js
assert.deepEqual(s, [2, 5, 7]);
```
# --seed--
## --seed-contents--
```js
const s = [5, 7, 2];
@ -61,14 +73,7 @@ function editInPlace() {
editInPlace();
```
</div>
</section>
## Solution
<section id='solution'>
# --solutions--
```js
const s = [5, 7, 2];
@ -79,5 +84,3 @@ function editInPlace() {
}
editInPlace();
```
</section>

View File

@ -5,9 +5,10 @@ challengeType: 1
forumTopicId: 301207
---
## Description
<section id='description'>
As seen in the previous challenge, <code>const</code> declaration alone doesn't really protect your data from mutation. To ensure your data doesn't change, JavaScript provides a function <code>Object.freeze</code> to prevent data mutation.
# --description--
As seen in the previous challenge, `const` declaration alone doesn't really protect your data from mutation. To ensure your data doesn't change, JavaScript provides a function `Object.freeze` to prevent data mutation.
Once the object is frozen, you can no longer add, update, or delete properties from it. Any attempt at changing the object will be rejected without an error.
```js
@ -22,35 +23,45 @@ console.log(obj);
// { name: "FreeCodeCamp", review:"Awesome"}
```
</section>
# --instructions--
## Instructions
<section id='instructions'>
In this challenge you are going to use <code>Object.freeze</code> to prevent mathematical constants from changing. You need to freeze the <code>MATH_CONSTANTS</code> object so that no one is able to alter the value of <code>PI</code>, add, or delete properties.
</section>
In this challenge you are going to use `Object.freeze` to prevent mathematical constants from changing. You need to freeze the `MATH_CONSTANTS` object so that no one is able to alter the value of `PI`, add, or delete properties.
## Tests
<section id='tests'>
# --hints--
```yml
tests:
- text: You should not replace <code>const</code> keyword.
testString: getUserInput => assert(getUserInput('index').match(/const/g));
- text: <code>MATH_CONSTANTS</code> should be a constant variable (by using <code>const</code>).
testString: getUserInput => assert(getUserInput('index').match(/const\s+MATH_CONSTANTS/g));
- text: You should not change original <code>MATH_CONSTANTS</code>.
testString: getUserInput => assert(getUserInput('index').match(/const\s+MATH_CONSTANTS\s+=\s+{\s+PI:\s+3.14\s+};/g));
- text: <code>PI</code> should equal <code>3.14</code>.
testString: assert(PI === 3.14);
You should not replace `const` keyword.
```js
(getUserInput) => assert(getUserInput('index').match(/const/g));
```
</section>
`MATH_CONSTANTS` should be a constant variable (by using `const`).
## Challenge Seed
<section id='challengeSeed'>
```js
(getUserInput) =>
assert(getUserInput('index').match(/const\s+MATH_CONSTANTS/g));
```
<div id='js-seed'>
You should not change original `MATH_CONSTANTS`.
```js
(getUserInput) =>
assert(
getUserInput('index').match(
/const\s+MATH_CONSTANTS\s+=\s+{\s+PI:\s+3.14\s+};/g
)
);
```
`PI` should equal `3.14`.
```js
assert(PI === 3.14);
```
# --seed--
## --seed-contents--
```js
function freezeObj() {
@ -71,14 +82,7 @@ function freezeObj() {
const PI = freezeObj();
```
</div>
</section>
## Solution
<section id='solution'>
# --solutions--
```js
function freezeObj() {
@ -96,5 +100,3 @@ function freezeObj() {
}
const PI = freezeObj();
```
</section>

View File

@ -5,45 +5,51 @@ challengeType: 1
forumTopicId: 301208
---
## Description
<section id='description'>
<code>import</code> allows you to choose which parts of a file or module to load. In the previous lesson, the examples exported <code>add</code> from the <code>math_functions.js</code> file. Here's how you can import it to use in another file:
# --description--
`import` allows you to choose which parts of a file or module to load. In the previous lesson, the examples exported `add` from the `math_functions.js` file. Here's how you can import it to use in another file:
```js
import { add } from './math_functions.js';
```
Here, <code>import</code> will find <code>add</code> in <code>math_functions.js</code>, import just that function for you to use, and ignore the rest. The <code>./</code> tells the import to look for the <code>math_functions.js</code> file in the same folder as the current file. The relative file path (<code>./</code>) and file extension (<code>.js</code>) are required when using import in this way.
Here, `import` will find `add` in `math_functions.js`, import just that function for you to use, and ignore the rest. The `./` tells the import to look for the `math_functions.js` file in the same folder as the current file. The relative file path (`./`) and file extension (`.js`) are required when using import in this way.
You can import more than one item from the file by adding them in the <code>import</code> statement like this:
You can import more than one item from the file by adding them in the `import` statement like this:
```js
import { add, subtract } from './math_functions.js';
```
</section>
# --instructions--
## Instructions
<section id='instructions'>
Add the appropriate <code>import</code> statement that will allow the current file to use the <code>uppercaseString</code> and <code>lowercaseString</code> functions you exported in the previous lesson. These functions are in a file called <code>string_functions.js</code>, which is in the same directory as the current file.
</section>
Add the appropriate `import` statement that will allow the current file to use the `uppercaseString` and `lowercaseString` functions you exported in the previous lesson. These functions are in a file called `string_functions.js`, which is in the same directory as the current file.
## Tests
<section id='tests'>
# --hints--
```yml
tests:
- text: You should properly import <code>uppercaseString</code>.
testString: assert(code.match(/import\s*{\s*(uppercaseString[^}]*|[^,]*,\s*uppercaseString\s*)}\s+from\s+('|")\.\/string_functions\.js\2/g));
- text: You should properly import <code>lowercaseString</code>.
testString: assert(code.match(/import\s*{\s*(lowercaseString[^}]*|[^,]*,\s*lowercaseString\s*)}\s+from\s+('|")\.\/string_functions\.js\2/g));
You should properly import `uppercaseString`.
```js
assert(
code.match(
/import\s*{\s*(uppercaseString[^}]*|[^,]*,\s*uppercaseString\s*)}\s+from\s+('|")\.\/string_functions\.js\2/g
)
);
```
</section>
You should properly import `lowercaseString`.
## Challenge Seed
<section id='challengeSeed'>
<div id='js-seed'>
```js
assert(
code.match(
/import\s*{\s*(lowercaseString[^}]*|[^,]*,\s*lowercaseString\s*)}\s+from\s+('|")\.\/string_functions\.js\2/g
)
);
```
# --seed--
## --seed-contents--
```js
@ -53,11 +59,7 @@ uppercaseString("hello");
lowercaseString("WORLD!");
```
</div>
</section>
## Solution
<section id='solution'>
# --solutions--
```js
import { uppercaseString, lowercaseString } from './string_functions.js';
@ -65,5 +67,3 @@ import { uppercaseString, lowercaseString } from './string_functions.js';
uppercaseString("hello");
lowercaseString("WORLD!");
```
</section>

View File

@ -5,9 +5,10 @@ challengeType: 1
forumTopicId: 301209
---
## Description
<section id='description'>
# --description--
In order to help us create more flexible functions, ES6 introduces <dfn>default parameters</dfn> for functions.
Check out this code:
```js
@ -17,34 +18,35 @@ console.log(greeting("John")); // Hello John
console.log(greeting()); // Hello Anonymous
```
The default parameter kicks in when the argument is not specified (it is undefined). As you can see in the example above, the parameter <code>name</code> will receive its default value <code>"Anonymous"</code> when you do not provide a value for the parameter. You can add default values for as many parameters as you want.
</section>
The default parameter kicks in when the argument is not specified (it is undefined). As you can see in the example above, the parameter `name` will receive its default value `"Anonymous"` when you do not provide a value for the parameter. You can add default values for as many parameters as you want.
## Instructions
<section id='instructions'>
Modify the function <code>increment</code> by adding default parameters so that it will add 1 to <code>number</code> if <code>value</code> is not specified.
</section>
# --instructions--
## Tests
<section id='tests'>
Modify the function `increment` by adding default parameters so that it will add 1 to `number` if `value` is not specified.
```yml
tests:
- text: The result of <code>increment(5, 2)</code> should be <code>7</code>.
testString: assert(increment(5, 2) === 7);
- text: The result of <code>increment(5)</code> should be <code>6</code>.
testString: assert(increment(5) === 6);
- text: A default parameter value of <code>1</code> should be used for <code>value</code>.
testString: assert(code.match(/value\s*=\s*1/g));
# --hints--
The result of `increment(5, 2)` should be `7`.
```js
assert(increment(5, 2) === 7);
```
</section>
The result of `increment(5)` should be `6`.
## Challenge Seed
<section id='challengeSeed'>
```js
assert(increment(5) === 6);
```
<div id='js-seed'>
A default parameter value of `1` should be used for `value`.
```js
assert(code.match(/value\s*=\s*1/g));
```
# --seed--
## --seed-contents--
```js
// Only change code below this line
@ -52,17 +54,8 @@ const increment = (number, value) => number + value;
// Only change code above this line
```
</div>
</section>
## Solution
<section id='solution'>
# --solutions--
```js
const increment = (number, value = 1) => number + value;
```
</section>

View File

@ -5,56 +5,49 @@ challengeType: 1
forumTopicId: 301210
---
## Description
<section id='description'>
Suppose you have a file and you wish to import all of its contents into the current file. This can be done with the <code>import * as</code> syntax. Here's an example where the contents of a file named <code>math_functions.js</code> are imported into a file in the same directory:
# --description--
Suppose you have a file and you wish to import all of its contents into the current file. This can be done with the `import * as` syntax. Here's an example where the contents of a file named `math_functions.js` are imported into a file in the same directory:
```js
import * as myMathModule from "./math_functions.js";
```
The above <code>import</code> statement will create an object called <code>myMathModule</code>. This is just a variable name, you can name it anything. The object will contain all of the exports from <code>math_functions.js</code> in it, so you can access the functions like you would any other object property. Here's how you can use the <code>add</code> and <code>subtract</code> functions that were imported:
The above `import` statement will create an object called `myMathModule`. This is just a variable name, you can name it anything. The object will contain all of the exports from `math_functions.js` in it, so you can access the functions like you would any other object property. Here's how you can use the `add` and `subtract` functions that were imported:
```js
myMathModule.add(2,3);
myMathModule.subtract(5,3);
```
</section>
# --instructions--
## Instructions
<section id='instructions'>
The code in this file requires the contents of the file: <code>string_functions.js</code>, that is in the same directory as the current file. Use the <code>import * as</code> syntax to import everything from the file into an object called <code>stringFunctions</code>.
</section>
The code in this file requires the contents of the file: `string_functions.js`, that is in the same directory as the current file. Use the `import * as` syntax to import everything from the file into an object called `stringFunctions`.
## Tests
<section id='tests'>
# --hints--
```yml
tests:
- text: Your code should properly use <code>import * as</code> syntax.
testString: assert(code.match(/import\s*\*\s*as\s+stringFunctions\s+from\s*('|")\.\/string_functions\.js\1/g));
```
</section>
## Challenge Seed
<section id='challengeSeed'>
<div id='js-seed'>
Your code should properly use `import * as` syntax.
```js
assert(
code.match(
/import\s*\*\s*as\s+stringFunctions\s+from\s*('|")\.\/string_functions\.js\1/g
)
);
```
# --seed--
## --seed-contents--
```js
// Only change code above this line
stringFunctions.uppercaseString("hello");
stringFunctions.lowercaseString("WORLD!");
```
</div>
</section>
## Solution
<section id='solution'>
# --solutions--
```js
import * as stringFunctions from "./string_functions.js";
@ -63,5 +56,3 @@ import * as stringFunctions from "./string_functions.js";
stringFunctions.uppercaseString("hello");
stringFunctions.lowercaseString("WORLD!");
```
</section>

View File

@ -5,9 +5,10 @@ challengeType: 1
forumTopicId: 301211
---
## Description
<section id='description'>
# --description--
In JavaScript, we often don't need to name our functions, especially when passing a function as an argument to another function. Instead, we create inline functions. We don't need to name these functions because we do not reuse them anywhere else.
To achieve this, we often use the following syntax:
```js
@ -17,7 +18,7 @@ const myFunc = function() {
}
```
ES6 provides us with the syntactic sugar to not have to write anonymous functions this way. Instead, you can use <strong>arrow function syntax</strong>:
ES6 provides us with the syntactic sugar to not have to write anonymous functions this way. Instead, you can use **arrow function syntax**:
```js
const myFunc = () => {
@ -26,44 +27,53 @@ const myFunc = () => {
}
```
When there is no function body, and only a return value, arrow function syntax allows you to omit the keyword <code>return</code> as well as the brackets surrounding the code. This helps simplify smaller functions into one-line statements:
When there is no function body, and only a return value, arrow function syntax allows you to omit the keyword `return` as well as the brackets surrounding the code. This helps simplify smaller functions into one-line statements:
```js
const myFunc = () => "value";
```
This code will still return the string <code>value</code> by default.
</section>
This code will still return the string `value` by default.
## Instructions
<section id='instructions'>
Rewrite the function assigned to the variable <code>magic</code> which returns a <code>new Date()</code> to use arrow function syntax. Also, make sure nothing is defined using the keyword <code>var</code>.
</section>
# --instructions--
## Tests
<section id='tests'>
Rewrite the function assigned to the variable `magic` which returns a `new Date()` to use arrow function syntax. Also, make sure nothing is defined using the keyword `var`.
```yml
tests:
- text: User should replace <code>var</code> keyword.
testString: getUserInput => assert(!getUserInput('index').match(/var/g));
- text: <code>magic</code> should be a constant variable (by using <code>const</code>).
testString: getUserInput => assert(getUserInput('index').match(/const\s+magic/g));
- text: <code>magic</code> should be a <code>function</code>.
testString: assert(typeof magic === 'function');
- text: <code>magic()</code> should return correct date.
testString: assert(magic().setHours(0,0,0,0) === new Date().setHours(0,0,0,0));
- text: <code>function</code> keyword should not be used.
testString: getUserInput => assert(!getUserInput('index').match(/function/g));
# --hints--
User should replace `var` keyword.
```js
(getUserInput) => assert(!getUserInput('index').match(/var/g));
```
</section>
`magic` should be a constant variable (by using `const`).
## Challenge Seed
<section id='challengeSeed'>
```js
(getUserInput) => assert(getUserInput('index').match(/const\s+magic/g));
```
<div id='js-seed'>
`magic` should be a `function`.
```js
assert(typeof magic === 'function');
```
`magic()` should return correct date.
```js
assert(magic().setHours(0, 0, 0, 0) === new Date().setHours(0, 0, 0, 0));
```
`function` keyword should not be used.
```js
(getUserInput) => assert(!getUserInput('index').match(/function/g));
```
# --seed--
## --seed-contents--
```js
var magic = function() {
@ -71,19 +81,10 @@ var magic = function() {
};
```
</div>
</section>
## Solution
<section id='solution'>
# --solutions--
```js
const magic = () => {
return new Date();
};
```
</section>

View File

@ -5,11 +5,13 @@ challengeType: 1
forumTopicId: 301212
---
## Description
<section id='description'>
# --description--
ES6 provides a new syntax to create objects, using the <dfn>class</dfn> keyword.
It should be noted that the <code>class</code> syntax is just syntax, and not a full-fledged class-based implementation of an object-oriented paradigm, unlike in languages such as Java, Python, Ruby, etc.
In ES5, we usually define a constructor function and use the <code>new</code> keyword to instantiate an object.
It should be noted that the `class` syntax is just syntax, and not a full-fledged class-based implementation of an object-oriented paradigm, unlike in languages such as Java, Python, Ruby, etc.
In ES5, we usually define a constructor function and use the `new` keyword to instantiate an object.
```js
var SpaceShuttle = function(targetPlanet){
@ -18,7 +20,7 @@ var SpaceShuttle = function(targetPlanet){
var zeus = new SpaceShuttle('Jupiter');
```
The <code>class</code> syntax simply replaces the constructor function creation:
The `class` syntax simply replaces the constructor function creation:
```js
class SpaceShuttle {
@ -29,40 +31,52 @@ class SpaceShuttle {
const zeus = new SpaceShuttle('Jupiter');
```
It should be noted that the <code>class</code> keyword declares a new function, to which a constructor is added. This constructor is invoked when <code>new</code> is called to create a new object.<br>
<strong>Notes:</strong><br><ul>
<li> UpperCamelCase should be used by convention for ES6 class names, as in <code>SpaceShuttle</code> used above.</li>
<li> The constructor method is a special method for creating and initializing an object created with a class. You will learn more about it in the Object Oriented Programming section of the JavaScript Algorithms And Data Structures Certification.</li></ul>
</section>
It should be noted that the `class` keyword declares a new function, to which a constructor is added. This constructor is invoked when `new` is called to create a new object.
**Notes:**
## Instructions
<section id='instructions'>
Use the <code>class</code> keyword and write a constructor to create the <code>Vegetable</code> class.
The <code>Vegetable</code> class allows you to create a vegetable object with a property <code>name</code> that gets passed to the constructor.
</section>
- UpperCamelCase should be used by convention for ES6 class names, as in `SpaceShuttle` used above.
- The constructor method is a special method for creating and initializing an object created with a class. You will learn more about it in the Object Oriented Programming section of the JavaScript Algorithms And Data Structures Certification.
## Tests
<section id='tests'>
# --instructions--
```yml
tests:
- text: <code>Vegetable</code> should be a <code>class</code> with a defined <code>constructor</code> method.
testString: assert(typeof Vegetable === 'function' && typeof Vegetable.constructor === 'function');
- text: <code>class</code> keyword should be used.
testString: assert(code.match(/class/g));
- text: <code>Vegetable</code> should be able to be instantiated.
testString: assert(() => {const a = new Vegetable("apple"); return typeof a === 'object';});
- text: <code>carrot.name</code> should return <code>carrot</code>.
testString: assert(carrot.name=='carrot');
Use the `class` keyword and write a constructor to create the `Vegetable` class.
The `Vegetable` class allows you to create a vegetable object with a property `name` that gets passed to the constructor.
# --hints--
`Vegetable` should be a `class` with a defined `constructor` method.
```js
assert(
typeof Vegetable === 'function' && typeof Vegetable.constructor === 'function'
);
```
</section>
`class` keyword should be used.
## Challenge Seed
<section id='challengeSeed'>
```js
assert(code.match(/class/g));
```
<div id='js-seed'>
`Vegetable` should be able to be instantiated.
```js
assert(() => {
const a = new Vegetable('apple');
return typeof a === 'object';
});
```
`carrot.name` should return `carrot`.
```js
assert(carrot.name == 'carrot');
```
# --seed--
## --seed-contents--
```js
// Only change code below this line
@ -73,14 +87,7 @@ const carrot = new Vegetable('carrot');
console.log(carrot.name); // Should display 'carrot'
```
</div>
</section>
## Solution
<section id='solution'>
# --solutions--
```js
class Vegetable {
@ -90,5 +97,3 @@ class Vegetable {
}
const carrot = new Vegetable('carrot');
```
</section>

View File

@ -5,10 +5,12 @@ challengeType: 1
forumTopicId: 301213
---
## Description
<section id='description'>
# --description--
ES6 makes destructuring arrays as easy as destructuring objects.
One key difference between the spread operator and array destructuring is that the spread operator unpacks all contents of an array into a comma-separated list. Consequently, you cannot pick or choose which elements you want to assign to variables.
Destructuring an array lets us do exactly that:
```js
@ -16,60 +18,49 @@ const [a, b] = [1, 2, 3, 4, 5, 6];
console.log(a, b); // 1, 2
```
The variable <code>a</code> is assigned the first value of the array, and <code>b</code> is assigned the second value of the array.
We can also access the value at any index in an array with destructuring by using commas to reach the desired index:
The variable `a` is assigned the first value of the array, and `b` is assigned the second value of the array. We can also access the value at any index in an array with destructuring by using commas to reach the desired index:
```js
const [a, b,,, c] = [1, 2, 3, 4, 5, 6];
console.log(a, b, c); // 1, 2, 5
```
</section>
# --instructions--
## Instructions
<section id='instructions'>
Use destructuring assignment to swap the values of <code>a</code> and <code>b</code> so that <code>a</code> receives the value stored in <code>b</code>, and <code>b</code> receives the value stored in <code>a</code>.
</section>
Use destructuring assignment to swap the values of `a` and `b` so that `a` receives the value stored in `b`, and `b` receives the value stored in `a`.
## Tests
<section id='tests'>
# --hints--
```yml
tests:
- text: Value of <code>a</code> should be 6, after swapping.
testString: assert(a === 6);
- text: Value of <code>b</code> should be 8, after swapping.
testString: assert(b === 8);
- text: You should use array destructuring to swap a and b.
testString: assert(/\[\s*(\w)\s*,\s*(\w)\s*\]\s*=\s*\[\s*\2\s*,\s*\1\s*\]/g.test(code));
Value of `a` should be 6, after swapping.
```js
assert(a === 6);
```
</section>
Value of `b` should be 8, after swapping.
## Challenge Seed
<section id='challengeSeed'>
```js
assert(b === 8);
```
<div id='js-seed'>
You should use array destructuring to swap a and b.
```js
assert(/\[\s*(\w)\s*,\s*(\w)\s*\]\s*=\s*\[\s*\2\s*,\s*\1\s*\]/g.test(code));
```
# --seed--
## --seed-contents--
```js
let a = 8, b = 6;
// Only change code below this line
```
</div>
</section>
## Solution
<section id='solution'>
# --solutions--
```js
let a = 8, b = 6;
[a, b] = [b, a];
```
</section>

View File

@ -5,8 +5,8 @@ challengeType: 1
forumTopicId: 301214
---
## Description
<section id='description'>
# --description--
You can use the same principles from the previous two lessons to destructure values from nested objects.
Using an object similar to previous examples:
@ -32,33 +32,50 @@ And here's how you can assign an object properties' values to variables with dif
const { johnDoe: { age: userAge, email: userEmail }} = user;
```
</section>
# --instructions--
## Instructions
<section id='instructions'>
Replace the two assignments with an equivalent destructuring assignment. It should still assign the variables <code>lowToday</code> and <code>highToday</code> the values of <code>today.low</code> and <code>today.high</code> from the <code>LOCAL_FORECAST</code> object.
</section>
Replace the two assignments with an equivalent destructuring assignment. It should still assign the variables `lowToday` and `highToday` the values of `today.low` and `today.high` from the `LOCAL_FORECAST` object.
## Tests
<section id='tests'>
# --hints--
```yml
tests:
- text: You should remove the ES5 assignment syntax.
testString: assert(!code.match(/lowToday = LOCAL_FORECAST\.today\.low/g) && !code.match(/highToday = LOCAL_FORECAST\.today.high/g))
- text: You should use destructuring to create the <code>lowToday</code> variable.
testString: assert(code.match(/(var|const|let)\s*{\s*today\s*:\s*{\s*(low\s*:\s*lowToday[^}]*|[^,]*,\s*low\s*:\s*lowToday\s*)}\s*}\s*=\s*LOCAL_FORECAST(;|\s+|\/\/)/g));
- text: You should use destructuring to create the <code>highToday</code> variable.
testString: assert(code.match(/(var|const|let)\s*{\s*today\s*:\s*{\s*(high\s*:\s*highToday[^}]*|[^,]*,\s*high\s*:\s*highToday\s*)}\s*}\s*=\s*LOCAL_FORECAST(;|\s+|\/\/)/g));
- text: <code>lowToday</code> should be equal to <code>64</code> and <code>highToday</code> should be equal to <code>77</code>.
testString: assert(lowToday === 64 && highToday === 77);
You should remove the ES5 assignment syntax.
```js
assert(
!code.match(/lowToday = LOCAL_FORECAST\.today\.low/g) &&
!code.match(/highToday = LOCAL_FORECAST\.today.high/g)
);
```
</section>
You should use destructuring to create the `lowToday` variable.
## Challenge Seed
<section id='challengeSeed'>
<div id='js-seed'>
```js
assert(
code.match(
/(var|const|let)\s*{\s*today\s*:\s*{\s*(low\s*:\s*lowToday[^}]*|[^,]*,\s*low\s*:\s*lowToday\s*)}\s*}\s*=\s*LOCAL_FORECAST(;|\s+|\/\/)/g
)
);
```
You should use destructuring to create the `highToday` variable.
```js
assert(
code.match(
/(var|const|let)\s*{\s*today\s*:\s*{\s*(high\s*:\s*highToday[^}]*|[^,]*,\s*high\s*:\s*highToday\s*)}\s*}\s*=\s*LOCAL_FORECAST(;|\s+|\/\/)/g
)
);
```
`lowToday` should be equal to `64` and `highToday` should be equal to `77`.
```js
assert(lowToday === 64 && highToday === 77);
```
# --seed--
## --seed-contents--
```js
const LOCAL_FORECAST = {
@ -75,11 +92,7 @@ const highToday = LOCAL_FORECAST.today.high;
// Only change code above this line
```
</div>
</section>
## Solution
<section id='solution'>
# --solutions--
```js
const LOCAL_FORECAST = {
@ -90,5 +103,3 @@ const LOCAL_FORECAST = {
const { today: { low: lowToday, high: highToday }} = LOCAL_FORECAST;
```
</section>

View File

@ -5,8 +5,8 @@ challengeType: 1
forumTopicId: 301215
---
## Description
<section id='description'>
# --description--
Destructuring allows you to assign a new variable name when extracting values. You can do this by putting the new name after a colon when assigning the value.
Using the same object from the last example:
@ -22,34 +22,52 @@ const { name: userName, age: userAge } = user;
// userName = 'John Doe', userAge = 34
```
You may read it as "get the value of <code>user.name</code> and assign it to a new variable named <code>userName</code>" and so on.
</section>
You may read it as "get the value of `user.name` and assign it to a new variable named `userName`" and so on.
## Instructions
<section id='instructions'>
Replace the two assignments with an equivalent destructuring assignment. It should still assign the variables <code>highToday</code> and <code>highTomorrow</code> the values of <code>today</code> and <code>tomorrow</code> from the <code>HIGH_TEMPERATURES</code> object.
</section>
# --instructions--
## Tests
<section id='tests'>
Replace the two assignments with an equivalent destructuring assignment. It should still assign the variables `highToday` and `highTomorrow` the values of `today` and `tomorrow` from the `HIGH_TEMPERATURES` object.
```yml
tests:
- text: You should remove the ES5 assignment syntax.
testString: assert(!code.match(/highToday = HIGH_TEMPERATURES\.today/g) && !code.match(/highTomorrow = HIGH_TEMPERATURES\.tomorrow/g))
- text: You should use destructuring to create the <code>highToday</code> variable.
testString: assert(code.match(/(var|const|let)\s*{\s*(today\s*:\s*highToday[^}]*|[^,]*,\s*today\s*:\s*highToday\s*)}\s*=\s*HIGH_TEMPERATURES(;|\s+|\/\/)/g));
- text: You should use destructuring to create the <code>highTomorrow</code> variable.
testString: assert(code.match(/(var|const|let)\s*{\s*(tomorrow\s*:\s*highTomorrow[^}]*|[^,]*,\s*tomorrow\s*:\s*highTomorrow\s*)}\s*=\s*HIGH_TEMPERATURES(;|\s+|\/\/)/g));
- text: <code>highToday</code> should be equal to <code>77</code> and <code>highTomorrow</code> should be equal to <code>80</code>.
testString: assert(highToday === 77 && highTomorrow === 80);
# --hints--
You should remove the ES5 assignment syntax.
```js
assert(
!code.match(/highToday = HIGH_TEMPERATURES\.today/g) &&
!code.match(/highTomorrow = HIGH_TEMPERATURES\.tomorrow/g)
);
```
</section>
You should use destructuring to create the `highToday` variable.
## Challenge Seed
<section id='challengeSeed'>
<div id='js-seed'>
```js
assert(
code.match(
/(var|const|let)\s*{\s*(today\s*:\s*highToday[^}]*|[^,]*,\s*today\s*:\s*highToday\s*)}\s*=\s*HIGH_TEMPERATURES(;|\s+|\/\/)/g
)
);
```
You should use destructuring to create the `highTomorrow` variable.
```js
assert(
code.match(
/(var|const|let)\s*{\s*(tomorrow\s*:\s*highTomorrow[^}]*|[^,]*,\s*tomorrow\s*:\s*highTomorrow\s*)}\s*=\s*HIGH_TEMPERATURES(;|\s+|\/\/)/g
)
);
```
`highToday` should be equal to `77` and `highTomorrow` should be equal to `80`.
```js
assert(highToday === 77 && highTomorrow === 80);
```
# --seed--
## --seed-contents--
```js
const HIGH_TEMPERATURES = {
@ -66,11 +84,7 @@ const highTomorrow = HIGH_TEMPERATURES.tomorrow;
// Only change code above this line
```
</div>
</section>
## Solution
<section id='solution'>
# --solutions--
```js
const HIGH_TEMPERATURES = {
@ -81,5 +95,3 @@ const HIGH_TEMPERATURES = {
const { today: highToday, tomorrow: highTomorrow } = HIGH_TEMPERATURES;
```
</section>

View File

@ -5,8 +5,8 @@ challengeType: 1
forumTopicId: 301216
---
## Description
<section id='description'>
# --description--
<dfn>Destructuring assignment</dfn> is special syntax introduced in ES6, for neatly assigning values taken directly from an object.
Consider the following ES5 code:
@ -25,37 +25,59 @@ const { name, age } = user;
// name = 'John Doe', age = 34
```
Here, the <code>name</code> and <code>age</code> variables will be created and assigned the values of their respective values from the <code>user</code> object. You can see how much cleaner this is.
Here, the `name` and `age` variables will be created and assigned the values of their respective values from the `user` object. You can see how much cleaner this is.
You can extract as many or few values from the object as you want.
</section>
## Instructions
<section id='instructions'>
Replace the two assignments with an equivalent destructuring assignment. It should still assign the variables <code>today</code> and <code>tomorrow</code> the values of <code>today</code> and <code>tomorrow</code> from the <code>HIGH_TEMPERATURES</code> object.
</section>
# --instructions--
## Tests
<section id='tests'>
Replace the two assignments with an equivalent destructuring assignment. It should still assign the variables `today` and `tomorrow` the values of `today` and `tomorrow` from the `HIGH_TEMPERATURES` object.
```yml
tests:
- text: You should remove the ES5 assignment syntax.
testString: assert(!__helpers.removeJSComments(code).match(/today\s*=\s*HIGH_TEMPERATURES\.(today|tomorrow)/g))
- text: You should use destructuring to create the <code>today</code> variable.
testString: assert(__helpers.removeJSComments(code).match(/(var|let|const)\s*{\s*(today[^}]*|[^,]*,\s*today)\s*}\s*=\s*HIGH_TEMPERATURES(;|\s+|\/\/)/g));
- text: You should use destructuring to create the <code>tomorrow</code> variable.
testString: assert(__helpers.removeJSComments(code).match(/(var|let|const)\s*{\s*(tomorrow[^}]*|[^,]*,\s*tomorrow)\s*}\s*=\s*HIGH_TEMPERATURES(;|\s+|\/\/)/g));
- text: <code>today</code> should be equal to <code>77</code> and <code>tomorrow</code> should be equal to <code>80</code>.
testString: assert(today === 77 && tomorrow === 80);
# --hints--
You should remove the ES5 assignment syntax.
```js
assert(
!__helpers
.removeJSComments(code)
.match(/today\s*=\s*HIGH_TEMPERATURES\.(today|tomorrow)/g)
);
```
</section>
You should use destructuring to create the `today` variable.
## Challenge Seed
<section id='challengeSeed'>
<div id='js-seed'>
```js
assert(
__helpers
.removeJSComments(code)
.match(
/(var|let|const)\s*{\s*(today[^}]*|[^,]*,\s*today)\s*}\s*=\s*HIGH_TEMPERATURES(;|\s+|\/\/)/g
)
);
```
You should use destructuring to create the `tomorrow` variable.
```js
assert(
__helpers
.removeJSComments(code)
.match(
/(var|let|const)\s*{\s*(tomorrow[^}]*|[^,]*,\s*tomorrow)\s*}\s*=\s*HIGH_TEMPERATURES(;|\s+|\/\/)/g
)
);
```
`today` should be equal to `77` and `tomorrow` should be equal to `80`.
```js
assert(today === 77 && tomorrow === 80);
```
# --seed--
## --seed-contents--
```js
const HIGH_TEMPERATURES = {
@ -72,12 +94,7 @@ const tomorrow = HIGH_TEMPERATURES.tomorrow;
// Only change code above this line
```
</div>
</section>
## Solution
<section id='solution'>
# --solutions--
```js
const HIGH_TEMPERATURES = {
@ -88,5 +105,3 @@ const HIGH_TEMPERATURES = {
const { today, tomorrow } = HIGH_TEMPERATURES;
```
</section>

View File

@ -5,9 +5,10 @@ challengeType: 1
forumTopicId: 301217
---
## Description
<section id='description'>
# --description--
In some cases, you can destructure the object in a function argument itself.
Consider the code below:
```js
@ -25,36 +26,41 @@ const profileUpdate = ({ name, age, nationality, location }) => {
}
```
When <code>profileData</code> is passed to the above function, the values are destructured from the function parameter for use within the function.
</section>
When `profileData` is passed to the above function, the values are destructured from the function parameter for use within the function.
## Instructions
<section id='instructions'>
Use destructuring assignment within the argument to the function <code>half</code> to send only <code>max</code> and <code>min</code> inside the function.
</section>
# --instructions--
## Tests
<section id='tests'>
Use destructuring assignment within the argument to the function `half` to send only `max` and `min` inside the function.
```yml
tests:
- text: <code>stats</code> should be an <code>object</code>.
testString: assert(typeof stats === 'object');
- text: <code>half(stats)</code> should be <code>28.015</code>
testString: assert(half(stats) === 28.015);
- text: Destructuring should be used.
testString: assert(__helpers.removeWhiteSpace(code).match(/half=\({\w+,\w+}\)/));
- text: Destructured parameter should be used.
testString: assert(!code.match(/stats\.max|stats\.min/));
# --hints--
`stats` should be an `object`.
```js
assert(typeof stats === 'object');
```
</section>
`half(stats)` should be `28.015`
## Challenge Seed
<section id='challengeSeed'>
```js
assert(half(stats) === 28.015);
```
<div id='js-seed'>
Destructuring should be used.
```js
assert(__helpers.removeWhiteSpace(code).match(/half=\({\w+,\w+}\)/));
```
Destructured parameter should be used.
```js
assert(!code.match(/stats\.max|stats\.min/));
```
# --seed--
## --seed-contents--
```js
const stats = {
@ -69,17 +75,9 @@ const stats = {
// Only change code below this line
const half = (stats) => (stats.max + stats.min) / 2.0;
// Only change code above this line
```
</div>
</section>
## Solution
<section id='solution'>
# --solutions--
```js
const stats = {
@ -93,5 +91,3 @@ const stats = {
const half = ( {max, min} ) => (max + min) / 2.0;
```
</section>

View File

@ -1,14 +1,17 @@
---
id: 587d7b8a367417b2b2512b4c
title: Use Destructuring Assignment with the Rest Parameter to Reassign Array Elements
title: >-
Use Destructuring Assignment with the Rest Parameter to Reassign Array
Elements
challengeType: 1
forumTopicId: 301218
---
## Description
<section id='description'>
# --description--
In some situations involving array destructuring, we might want to collect the rest of the elements into a separate array.
The result is similar to <code>Array.prototype.slice()</code>, as shown below:
The result is similar to `Array.prototype.slice()`, as shown below:
```js
const [a, b, ...arr] = [1, 2, 3, 4, 5, 7];
@ -16,37 +19,45 @@ console.log(a, b); // 1, 2
console.log(arr); // [3, 4, 5, 7]
```
Variables <code>a</code> and <code>b</code> take the first and second values from the array. After that, because of the rest parameter's presence, <code>arr</code> gets the rest of the values in the form of an array.
The rest element only works correctly as the last variable in the list. As in, you cannot use the rest parameter to catch a subarray that leaves out the last element of the original array.
</section>
Variables `a` and `b` take the first and second values from the array. After that, because of the rest parameter's presence, `arr` gets the rest of the values in the form of an array. The rest element only works correctly as the last variable in the list. As in, you cannot use the rest parameter to catch a subarray that leaves out the last element of the original array.
## Instructions
<section id='instructions'>
Use destructuring assignment with the rest parameter to perform an effective <code>Array.prototype.slice()</code> so that <code>arr</code> is a sub-array of the original array <code>source</code> with the first two elements omitted.
</section>
# --instructions--
## Tests
<section id='tests'>
Use destructuring assignment with the rest parameter to perform an effective `Array.prototype.slice()` so that `arr` is a sub-array of the original array `source` with the first two elements omitted.
```yml
tests:
- text: <code>arr</code> should be <code>[3,4,5,6,7,8,9,10]</code>
testString: assert(arr.every((v, i) => v === i + 3) && arr.length === 8);
- text: <code>source</code> should be <code>[1,2,3,4,5,6,7,8,9,10]</code>
testString: assert(source.every((v, i) => v === i + 1) && source.length === 10);
- text: <code>Array.slice()</code> should not be used.
testString: getUserInput => assert(!getUserInput('index').match(/slice/g));
- text: Destructuring on <code>list</code> should be used.
testString: assert(__helpers.removeWhiteSpace(code).match(/\[(([_$a-z]\w*)?,){1,}\.\.\.arr\]=list/i));
# --hints--
`arr` should be `[3,4,5,6,7,8,9,10]`
```js
assert(arr.every((v, i) => v === i + 3) && arr.length === 8);
```
</section>
`source` should be `[1,2,3,4,5,6,7,8,9,10]`
## Challenge Seed
<section id='challengeSeed'>
```js
assert(source.every((v, i) => v === i + 1) && source.length === 10);
```
<div id='js-seed'>
`Array.slice()` should not be used.
```js
(getUserInput) => assert(!getUserInput('index').match(/slice/g));
```
Destructuring on `list` should be used.
```js
assert(
__helpers
.removeWhiteSpace(code)
.match(/\[(([_$a-z]\w*)?,){1,}\.\.\.arr\]=list/i)
);
```
# --seed--
## --seed-contents--
```js
const source = [1,2,3,4,5,6,7,8,9,10];
@ -57,17 +68,9 @@ function removeFirstTwo(list) {
return arr;
}
const arr = removeFirstTwo(source);
```
</div>
</section>
## Solution
<section id='solution'>
# --solutions--
```js
const source = [1,2,3,4,5,6,7,8,9,10];
@ -77,5 +80,3 @@ function removeFirstTwo(list) {
}
const arr = removeFirstTwo(source);
```
</section>

View File

@ -5,9 +5,9 @@ challengeType: 1
forumTopicId: 301219
---
## Description
<section id='description'>
Imagine a file called <code>math_functions.js</code> that contains several functions related to mathematical operations. One of them is stored in a variable, <code>add</code>, that takes in two numbers and returns their sum. You want to use this function in several different JavaScript files. In order to share it with these other files, you first need to <code>export</code> it.
# --description--
Imagine a file called `math_functions.js` that contains several functions related to mathematical operations. One of them is stored in a variable, `add`, that takes in two numbers and returns their sum. You want to use this function in several different JavaScript files. In order to share it with these other files, you first need to `export` it.
```js
export const add = (x, y) => {
@ -31,29 +31,35 @@ When you export a variable or function, you can import it in another file and us
export { add, subtract };
```
</section>
# --instructions--
## Instructions
<section id='instructions'>
There are two string-related functions in the editor. Export both of them using the method of your choice.
</section>
## Tests
<section id='tests'>
# --hints--
```yml
tests:
- text: You should properly export <code>uppercaseString</code>.
testString: assert(code.match(/(export\s+const\s+uppercaseString|export\s*{\s*(uppercaseString[^}]*|[^,]*,\s*uppercaseString\s*)})/g));
- text: You should properly export <code>lowercaseString</code>.
testString: assert(code.match(/(export\s+const\s+lowercaseString|export\s*{\s*(lowercaseString[^}]*|[^,]*,\s*lowercaseString\s*)})/g));
You should properly export `uppercaseString`.
```js
assert(
code.match(
/(export\s+const\s+uppercaseString|export\s*{\s*(uppercaseString[^}]*|[^,]*,\s*uppercaseString\s*)})/g
)
);
```
</section>
You should properly export `lowercaseString`.
## Challenge Seed
<section id='challengeSeed'>
<div id='js-seed'>
```js
assert(
code.match(
/(export\s+const\s+lowercaseString|export\s*{\s*(lowercaseString[^}]*|[^,]*,\s*lowercaseString\s*)})/g
)
);
```
# --seed--
## --seed-contents--
```js
const uppercaseString = (string) => {
@ -65,11 +71,7 @@ const lowercaseString = (string) => {
}
```
</div>
</section>
## Solution
<section id='solution'>
# --solutions--
```js
export const uppercaseString = (string) => {
@ -80,5 +82,3 @@ export const lowercaseString = (string) => {
return string.toLowerCase()
}
```
</section>

View File

@ -5,12 +5,15 @@ challengeType: 1
forumTopicId: 301220
---
## Description
<section id='description'>
# --description--
You can obtain values from an object and set the value of a property within an object.
These are classically called <dfn>getters</dfn> and <dfn>setters</dfn>.
Getter functions are meant to simply return (get) the value of an object's private variable to the user without the user directly accessing the private variable.
Setter functions are meant to modify (set) the value of an object's private variable based on the value passed into the setter function. This change could involve calculations, or even overwriting the previous value completely.<br><br>
Setter functions are meant to modify (set) the value of an object's private variable based on the value passed into the setter function. This change could involve calculations, or even overwriting the previous value completely.
```js
class Book {
@ -32,49 +35,106 @@ novel.writer = 'newAuthor';
console.log(novel.writer); // newAuthor
```
Notice the syntax used to invoke the getter and setter. They do not even look like functions.
Getters and setters are important because they hide internal implementation details.
<strong>Note:</strong> It is convention to precede the name of a private variable with an underscore (<code>_</code>). However, the practice itself does not make a variable private.
</section>
Notice the syntax used to invoke the getter and setter. They do not even look like functions. Getters and setters are important because they hide internal implementation details. **Note:** It is convention to precede the name of a private variable with an underscore (`_`). However, the practice itself does not make a variable private.
# --instructions--
Use the `class` keyword to create a Thermostat class. The constructor accepts a Fahrenheit temperature.
In the class, create a `getter` to obtain the temperature in Celsius and a `setter` to set the temperature in Celsius.
Remember that `C = 5/9 * (F - 32)` and `F = C * 9.0 / 5 + 32`, where `F` is the value of temperature in Fahrenheit, and `C` is the value of the same temperature in Celsius.
**Note:** When you implement this, you will track the temperature inside the class in one scale, either Fahrenheit or Celsius.
## Instructions
<section id='instructions'>
Use the <code>class</code> keyword to create a Thermostat class. The constructor accepts a Fahrenheit temperature.
In the class, create a <code>getter</code> to obtain the temperature in Celsius and a <code>setter</code> to set the temperature in Celsius.
Remember that <code>C = 5/9 * (F - 32)</code> and <code>F = C * 9.0 / 5 + 32</code>, where <code>F</code> is the value of temperature in Fahrenheit, and <code>C</code> is the value of the same temperature in Celsius.
<strong>Note:</strong> When you implement this, you will track the temperature inside the class in one scale, either Fahrenheit or Celsius.
This is the power of a getter and a setter. You are creating an API for another user, who can get the correct result regardless of which one you track.
In other words, you are abstracting implementation details from the user.
</section>
## Tests
<section id='tests'>
# --hints--
```yml
tests:
- text: <code>Thermostat</code> should be a <code>class</code> with a defined <code>constructor</code> method.
testString: assert(typeof Thermostat === 'function' && typeof Thermostat.constructor === 'function');
- text: <code>class</code> keyword should be used.
testString: assert(code.match(/class/g));
- text: <code>Thermostat</code> should be able to be instantiated.
testString: assert((() => {const t = new Thermostat(122);return typeof t === 'object'})());
- text: When instantiated with a Fahrenheit value, <code>Thermostat</code> should set the correct temperature.
testString: assert((() => {const t = new Thermostat(122);return t.temperature === 50})());
- text: A <code>getter</code> should be defined.
testString: assert((() => {const desc = Object.getOwnPropertyDescriptor(Thermostat.prototype, 'temperature');return !!desc && typeof desc.get === 'function';})());
- text: A <code>setter</code> should be defined.
testString: assert((() => {const desc = Object.getOwnPropertyDescriptor(Thermostat.prototype, 'temperature');return !!desc && typeof desc.set === 'function';})());
- text: Calling the <code>setter</code> with a Celsius value should set the temperature.
testString: assert((() => {const t = new Thermostat(32); t.temperature = 26; const u = new Thermostat(32); u.temperature = 50; return t.temperature === 26 && u.temperature === 50;})());
`Thermostat` should be a `class` with a defined `constructor` method.
```js
assert(
typeof Thermostat === 'function' &&
typeof Thermostat.constructor === 'function'
);
```
</section>
`class` keyword should be used.
## Challenge Seed
<section id='challengeSeed'>
```js
assert(code.match(/class/g));
```
<div id='js-seed'>
`Thermostat` should be able to be instantiated.
```js
assert(
(() => {
const t = new Thermostat(122);
return typeof t === 'object';
})()
);
```
When instantiated with a Fahrenheit value, `Thermostat` should set the correct temperature.
```js
assert(
(() => {
const t = new Thermostat(122);
return t.temperature === 50;
})()
);
```
A `getter` should be defined.
```js
assert(
(() => {
const desc = Object.getOwnPropertyDescriptor(
Thermostat.prototype,
'temperature'
);
return !!desc && typeof desc.get === 'function';
})()
);
```
A `setter` should be defined.
```js
assert(
(() => {
const desc = Object.getOwnPropertyDescriptor(
Thermostat.prototype,
'temperature'
);
return !!desc && typeof desc.set === 'function';
})()
);
```
Calling the `setter` with a Celsius value should set the temperature.
```js
assert(
(() => {
const t = new Thermostat(32);
t.temperature = 26;
const u = new Thermostat(32);
u.temperature = 50;
return t.temperature === 26 && u.temperature === 50;
})()
);
```
# --seed--
## --seed-contents--
```js
// Only change code below this line
@ -87,14 +147,7 @@ thermos.temperature = 26;
temp = thermos.temperature; // 26 in Celsius
```
</div>
</section>
## Solution
<section id='solution'>
# --solutions--
```js
class Thermostat {
@ -114,5 +167,3 @@ let temp = thermos.temperature; // 24.44 in Celsius
thermos.temperature = 26;
temp = thermos.temperature; // 26 in Celsius
```
</section>

View File

@ -5,9 +5,10 @@ challengeType: 1
forumTopicId: 301221
---
## Description
<section id='description'>
# --description--
In order to help us create more flexible functions, ES6 introduces the <dfn>rest parameter</dfn> for function parameters. With the rest parameter, you can create functions that take a variable number of arguments. These arguments are stored in an array that can be accessed later from inside the function.
Check out this code:
```js
@ -18,38 +19,47 @@ console.log(howMany(0, 1, 2)); // You have passed 3 arguments.
console.log(howMany("string", null, [1, 2, 3], { })); // You have passed 4 arguments.
```
The rest parameter eliminates the need to check the <code>args</code> array and allows us to apply <code>map()</code>, <code>filter()</code> and <code>reduce()</code> on the parameters array.
</section>
The rest parameter eliminates the need to check the `args` array and allows us to apply `map()`, `filter()` and `reduce()` on the parameters array.
## Instructions
<section id='instructions'>
Modify the function <code>sum</code> using the rest parameter in such a way that the function <code>sum</code> is able to take any number of arguments and return their sum.
</section>
# --instructions--
## Tests
<section id='tests'>
Modify the function `sum` using the rest parameter in such a way that the function `sum` is able to take any number of arguments and return their sum.
```yml
tests:
- text: The result of <code>sum(0,1,2)</code> should be 3
testString: assert(sum(0,1,2) === 3);
- text: The result of <code>sum(1,2,3,4)</code> should be 10
testString: assert(sum(1,2,3,4) === 10);
- text: The result of <code>sum(5)</code> should be 5
testString: assert(sum(5) === 5);
- text: The result of <code>sum()</code> should be 0
testString: assert(sum() === 0);
- text: The <code>sum</code> function should use the <code>...</code> rest parameter on the <code>args</code> parameter.
testString: assert(__helpers.removeWhiteSpace(code).match(/sum=\(\.\.\.args\)=>/));
# --hints--
The result of `sum(0,1,2)` should be 3
```js
assert(sum(0, 1, 2) === 3);
```
</section>
The result of `sum(1,2,3,4)` should be 10
## Challenge Seed
<section id='challengeSeed'>
```js
assert(sum(1, 2, 3, 4) === 10);
```
<div id='js-seed'>
The result of `sum(5)` should be 5
```js
assert(sum(5) === 5);
```
The result of `sum()` should be 0
```js
assert(sum() === 0);
```
The `sum` function should use the `...` rest parameter on the `args` parameter.
```js
assert(__helpers.removeWhiteSpace(code).match(/sum=\(\.\.\.args\)=>/));
```
# --seed--
## --seed-contents--
```js
const sum = (x, y, z) => {
@ -58,19 +68,10 @@ const sum = (x, y, z) => {
}
```
</div>
</section>
## Solution
<section id='solution'>
# --solutions--
```js
const sum = (...args) => {
return args.reduce((a, b) => a + b, 0);
}
```
</section>

View File

@ -5,58 +5,60 @@ challengeType: 1
forumTopicId: 301222
---
## Description
<section id='description'>
# --description--
ES6 introduces the <dfn>spread operator</dfn>, which allows us to expand arrays and other expressions in places where multiple parameters or elements are expected.
The ES5 code below uses <code>apply()</code> to compute the maximum value in an array:
The ES5 code below uses `apply()` to compute the maximum value in an array:
```js
var arr = [6, 89, 3, 45];
var maximus = Math.max.apply(null, arr); // returns 89
```
We had to use <code>Math.max.apply(null, arr)</code> because <code>Math.max(arr)</code> returns <code>NaN</code>. <code>Math.max()</code> expects comma-separated arguments, but not an array.
The spread operator makes this syntax much better to read and maintain.
We had to use `Math.max.apply(null, arr)` because `Math.max(arr)` returns `NaN`. `Math.max()` expects comma-separated arguments, but not an array. The spread operator makes this syntax much better to read and maintain.
```js
const arr = [6, 89, 3, 45];
const maximus = Math.max(...arr); // returns 89
```
<code>...arr</code> returns an unpacked array. In other words, it <em>spreads</em> the array.
However, the spread operator only works in-place, like in an argument to a function or in an array literal. The following code will not work:
`...arr` returns an unpacked array. In other words, it *spreads* the array. However, the spread operator only works in-place, like in an argument to a function or in an array literal. The following code will not work:
```js
const spreaded = ...arr; // will throw a syntax error
```
</section>
# --instructions--
## Instructions
<section id='instructions'>
Copy all contents of <code>arr1</code> into another array <code>arr2</code> using the spread operator.
</section>
Copy all contents of `arr1` into another array `arr2` using the spread operator.
## Tests
<section id='tests'>
# --hints--
```yml
tests:
- text: <code>arr2</code> should be correct copy of <code>arr1</code>.
testString: assert(arr2.every((v, i) => v === arr1[i]) && arr2.length);
- text: <code>...</code> spread operator should be used to duplicate <code>arr1</code>.
testString: assert(code.match(/Array\(\s*\.\.\.arr1\s*\)|\[\s*\.\.\.arr1\s*\]/));
- text: <code>arr2</code> should remain unchanged when <code>arr1</code> is changed.
testString: assert((arr1, arr2) => {arr1.push('JUN'); return arr2.length < arr1.length});
`arr2` should be correct copy of `arr1`.
```js
assert(arr2.every((v, i) => v === arr1[i]) && arr2.length);
```
</section>
`...` spread operator should be used to duplicate `arr1`.
## Challenge Seed
<section id='challengeSeed'>
```js
assert(code.match(/Array\(\s*\.\.\.arr1\s*\)|\[\s*\.\.\.arr1\s*\]/));
```
<div id='js-seed'>
`arr2` should remain unchanged when `arr1` is changed.
```js
assert((arr1, arr2) => {
arr1.push('JUN');
return arr2.length < arr1.length;
});
```
# --seed--
## --seed-contents--
```js
const arr1 = ['JAN', 'FEB', 'MAR', 'APR', 'MAY'];
@ -67,14 +69,7 @@ arr2 = []; // Change this line
console.log(arr2);
```
</div>
</section>
## Solution
<section id='solution'>
# --solutions--
```js
const arr1 = ['JAN', 'FEB', 'MAR', 'APR', 'MAY'];
@ -82,5 +77,3 @@ let arr2;
arr2 = [...arr1];
```
</section>

View File

@ -5,8 +5,8 @@ challengeType: 1
forumTopicId: 301223
---
## Description
<section id='description'>
# --description--
Just like a regular function, you can pass arguments into an arrow function.
```js
@ -30,37 +30,48 @@ const multiplier = (item, multi) => item * multi;
multiplier(4, 2); // returns 8
```
</section>
# --instructions--
## Instructions
<section id='instructions'>
Rewrite the <code>myConcat</code> function which appends contents of <code>arr2</code> to <code>arr1</code> so that the function uses arrow function syntax.
</section>
Rewrite the `myConcat` function which appends contents of `arr2` to `arr1` so that the function uses arrow function syntax.
## Tests
<section id='tests'>
# --hints--
```yml
tests:
- text: You should replace the <code>var</code> keyword.
testString: getUserInput => assert(!getUserInput('index').match(/var/g));
- text: <code>myConcat</code> should be a constant variable (by using <code>const</code>).
testString: getUserInput => assert(getUserInput('index').match(/const\s+myConcat/g));
- text: <code>myConcat</code> should be an arrow function with two parameters
testString: assert(/myConcat=\(\w+,\w+\)=>/.test(code.replace(/\s/g, '')) && typeof myConcat === 'function');
- text: <code>myConcat()</code> should return <code>[1, 2, 3, 4, 5]</code>.
testString: assert.deepEqual(myConcat([1, 2], [3, 4, 5]), [1, 2, 3, 4, 5]);
- text: <code>function</code> keyword should not be used.
testString: getUserInput => assert(!getUserInput('index').match(/function/g));
You should replace the `var` keyword.
```js
(getUserInput) => assert(!getUserInput('index').match(/var/g));
```
</section>
`myConcat` should be a constant variable (by using `const`).
## Challenge Seed
<section id='challengeSeed'>
```js
(getUserInput) => assert(getUserInput('index').match(/const\s+myConcat/g));
```
<div id='js-seed'>
`myConcat` should be an arrow function with two parameters
```js
assert(
/myConcat=\(\w+,\w+\)=>/.test(code.replace(/\s/g, '')) &&
typeof myConcat === 'function'
);
```
`myConcat()` should return `[1, 2, 3, 4, 5]`.
```js
assert.deepEqual(myConcat([1, 2], [3, 4, 5]), [1, 2, 3, 4, 5]);
```
`function` keyword should not be used.
```js
(getUserInput) => assert(!getUserInput('index').match(/function/g));
```
# --seed--
## --seed-contents--
```js
var myConcat = function(arr1, arr2) {
@ -70,14 +81,7 @@ var myConcat = function(arr1, arr2) {
console.log(myConcat([1, 2], [3, 4, 5]));
```
</div>
</section>
## Solution
<section id='solution'>
# --solutions--
```js
const myConcat = (arr1, arr2) => {
@ -86,5 +90,3 @@ const myConcat = (arr1, arr2) => {
console.log(myConcat([1, 2], [3, 4, 5]));
```
</section>

View File

@ -5,9 +5,9 @@ challengeType: 1
forumTopicId: 301224
---
## Description
<section id='description'>
When defining functions within objects in ES5, we have to use the keyword <code>function</code> as follows:
# --description--
When defining functions within objects in ES5, we have to use the keyword `function` as follows:
```js
const person = {
@ -18,7 +18,7 @@ const person = {
};
```
With ES6, You can remove the <code>function</code> keyword and colon altogether when defining functions in objects. Here's an example of this syntax:
With ES6, You can remove the `function` keyword and colon altogether when defining functions in objects. Here's an example of this syntax:
```js
const person = {
@ -29,33 +29,35 @@ const person = {
};
```
</section>
# --instructions--
## Instructions
<section id='instructions'>
Refactor the function <code>setGear</code> inside the object <code>bicycle</code> to use the shorthand syntax described above.
</section>
Refactor the function `setGear` inside the object `bicycle` to use the shorthand syntax described above.
## Tests
<section id='tests'>
# --hints--
```yml
tests:
- text: Traditional function expression should not be used.
testString: getUserInput => assert(!__helpers.removeJSComments(code).match(/function/));
- text: <code>setGear</code> should be a declarative function.
testString: assert(typeof bicycle.setGear === 'function' && code.match(/setGear\s*\(.+\)\s*\{/));
- text: <code>bicycle.setGear(48)</code> should change the <code>gear</code> value to 48.
testString: assert((new bicycle.setGear(48)).gear === 48);
Traditional function expression should not be used.
```js
(getUserInput) => assert(!__helpers.removeJSComments(code).match(/function/));
```
</section>
`setGear` should be a declarative function.
## Challenge Seed
<section id='challengeSeed'>
```js
assert(
typeof bicycle.setGear === 'function' && code.match(/setGear\s*\(.+\)\s*\{/)
);
```
<div id='js-seed'>
`bicycle.setGear(48)` should change the `gear` value to 48.
```js
assert(new bicycle.setGear(48).gear === 48);
```
# --seed--
## --seed-contents--
```js
// Only change code below this line
@ -70,12 +72,7 @@ bicycle.setGear(3);
console.log(bicycle.gear);
```
</div>
</section>
## Solution
<section id='solution'>
# --solutions--
```js
const bicycle = {
@ -86,5 +83,3 @@ const bicycle = {
};
bicycle.setGear(3);
```
</section>

View File

@ -5,9 +5,10 @@ challengeType: 1
forumTopicId: 301225
---
## Description
<section id='description'>
# --description--
ES6 adds some nice support for easily defining object literals.
Consider the following code:
```js
@ -17,39 +18,36 @@ const getMousePosition = (x, y) => ({
});
```
<code>getMousePosition</code> is a simple function that returns an object containing two properties.
ES6 provides the syntactic sugar to eliminate the redundancy of having to write <code>x: x</code>. You can simply write <code>x</code> once, and it will be converted to<code>x: x</code> (or something equivalent) under the hood.
Here is the same function from above rewritten to use this new syntax:
`getMousePosition` is a simple function that returns an object containing two properties. ES6 provides the syntactic sugar to eliminate the redundancy of having to write `x: x`. You can simply write `x` once, and it will be converted to`x: x` (or something equivalent) under the hood. Here is the same function from above rewritten to use this new syntax:
```js
const getMousePosition = (x, y) => ({ x, y });
```
</section>
# --instructions--
## Instructions
<section id='instructions'>
Use object property shorthand with object literals to create and return an object with <code>name</code>, <code>age</code> and <code>gender</code> properties.
</section>
Use object property shorthand with object literals to create and return an object with `name`, `age` and `gender` properties.
## Tests
<section id='tests'>
# --hints--
```yml
tests:
- text: '<code>createPerson("Zodiac Hasbro", 56, "male")</code> should return <code>{name: "Zodiac Hasbro", age: 56, gender: "male"}</code>.'
testString: assert.deepEqual({name:"Zodiac Hasbro",age:56,gender:"male"}, createPerson("Zodiac Hasbro", 56, "male"));
- text: Your code should not use <code>key:value</code>.
testString: getUserInput => assert(!getUserInput('index').match(/:/g));
`createPerson("Zodiac Hasbro", 56, "male")` should return `{name: "Zodiac Hasbro", age: 56, gender: "male"}`.
```js
assert.deepEqual(
{ name: 'Zodiac Hasbro', age: 56, gender: 'male' },
createPerson('Zodiac Hasbro', 56, 'male')
);
```
</section>
Your code should not use `key:value`.
## Challenge Seed
<section id='challengeSeed'>
```js
(getUserInput) => assert(!getUserInput('index').match(/:/g));
```
<div id='js-seed'>
# --seed--
## --seed-contents--
```js
const createPerson = (name, age, gender) => {
@ -63,14 +61,7 @@ const createPerson = (name, age, gender) => {
};
```
</div>
</section>
## Solution
<section id='solution'>
# --solutions--
```js
const createPerson = (name, age, gender) => {
@ -81,5 +72,3 @@ const createPerson = (name, age, gender) => {
};
};
```
</section>