chore(i8n,learn): processed translations

This commit is contained in:
Crowdin Bot
2021-02-06 04:42:36 +00:00
committed by Mrugesh Mohapatra
parent 15047f2d90
commit e5c44a3ae5
3274 changed files with 172122 additions and 14164 deletions

View File

@ -0,0 +1,134 @@
---
id: 587d7b87367417b2b2512b40
title: Compare Scopes of the var and let Keywords
challengeType: 1
forumTopicId: 301195
dashedName: compare-scopes-of-the-var-and-let-keywords
---
# --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
var numArray = [];
for (var i = 0; i < 3; i++) {
numArray.push(i);
}
console.log(numArray);
// returns [0, 1, 2]
console.log(i);
// returns 3
```
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 = [];
var i;
for (i = 0; i < 3; i++) {
numArray.push(i);
}
console.log(numArray);
// returns [0, 1, 2]
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 `i` variable. This is because the stored function will always refer to the value of the updated global `i` variable.
```js
var printNumTwo;
for (var i = 0; i < 3; i++) {
if (i === 2) {
printNumTwo = function() {
return i;
};
}
}
console.log(printNumTwo());
// returns 3
```
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;
for (let i = 0; i < 3; i++) {
if (i === 2) {
printNumTwo = function() {
return i;
};
}
}
console.log(printNumTwo());
// returns 2
console.log(i);
// returns "i is not defined"
```
`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--
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.
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));
```
The variable `i` declared in the if statement should equal "block scope".
```js
(getUserInput) =>
assert(
getUserInput('index').match(/(i\s*=\s*).*\s*.*\s*.*\1('|")block\s*scope\2/g)
);
```
`checkScope()` should return "function scope"
```js
assert(checkScope() === 'function scope');
```
# --seed--
## --seed-contents--
```js
function checkScope() {
var i = 'function scope';
if (true) {
i = 'block scope';
console.log('Block scope i is: ', i);
}
console.log('Function scope i is: ', i);
return i;
}
```
# --solutions--
```js
function checkScope() {
let i = 'function scope';
if (true) {
let i = 'block scope';
console.log('Block scope i is: ', i);
}
console.log('Function scope i is: ', i);
return i;
}
```

View File

@ -0,0 +1,85 @@
---
id: 5cdafbc32913098997531680
title: Complete a Promise with resolve and reject
challengeType: 1
forumTopicId: 301196
dashedName: complete-a-promise-with-resolve-and-reject
---
# --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) => {
if(condition here) {
resolve("Promise was fulfilled");
} else {
reject("Promise was rejected");
}
});
```
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.
# --instructions--
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`.
# --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
)
);
```
`reject` should be called with the expected string when the `if` condition is `false`.
```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 {
// Change this line
}
});
```
# --solutions--
```js
const makeServerRequest = new Promise((resolve, reject) => {
// responseFromServer represents a response from a server
let responseFromServer;
if(responseFromServer) {
resolve("We got the data");
} else {
reject("Data not received");
}
});
```

View File

@ -0,0 +1,53 @@
---
id: 5cdafbb0291309899753167f
title: Create a JavaScript Promise
challengeType: 1
forumTopicId: 301197
dashedName: create-a-javascript-promise
---
# --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) => {
});
```
# --instructions--
Create a new promise called `makeServerRequest`. Pass in a function with `resolve` and `reject` parameters to the constructor.
# --hints--
You should assign a promise to a declared variable named `makeServerRequest`.
```js
assert(makeServerRequest instanceof Promise);
```
Your promise should receive a function with `resolve` and `reject` as parameters.
```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) => {
});
```

View File

@ -0,0 +1,73 @@
---
id: 5cddbfd622f1a59093ec611d
title: Create a Module Script
challengeType: 6
forumTopicId: 301198
dashedName: create-a-module-script
---
# --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 `module` type can now use the `import` and `export` features you will learn about in the upcoming challenges.
# --instructions--
Add a script to the HTML document of type `module` and give it the source file of `index.js`
# --hints--
You should create a `script` tag.
```js
assert(code.match(/<\s*script[^>]*>\s*<\/\s*script\s*>/g));
```
Your `script` tag should be of type `module`.
```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>
<body>
<!-- Only change code below this line -->
<!-- Only change code above this line -->
</body>
</html>
```
# --solutions--
```html
<html>
<body>
<script type="module" src="index.js"></script>
</body>
</html>
```

View File

@ -0,0 +1,63 @@
---
id: 587d7b8c367417b2b2512b58
title: Create an Export Fallback with export default
challengeType: 1
forumTopicId: 301199
dashedName: create-an-export-fallback-with-export-default
---
# --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
export default function add(x, y) {
return x + y;
}
// anonymous function
export default function(x, y) {
return x + y;
}
```
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--
The following function should be the fallback value for the module. Please add the necessary code to do so.
# --hints--
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
)
);
```
# --seed--
## --seed-contents--
```js
function subtract(x, y) {
return x - y;
}
```
# --solutions--
```js
export default function subtract(x, y) {
return x - y;
}
```

View File

@ -0,0 +1,118 @@
---
id: 587d7b8a367417b2b2512b4e
title: Create Strings using Template Literals
challengeType: 1
forumTopicId: 301200
dashedName: create-strings-using-template-literals
---
# --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
const person = {
name: "Zodiac Hasbro",
age: 56
};
// Template literal with multi-line and string interpolation
const greeting = `Hello, my name is ${person.name}!
I am ${person.age} years old.`;
console.log(greeting); // prints
// Hello, my name is Zodiac Hasbro!
// I am 56 years old.
```
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.
Use an iterator method (any kind of loop) to get the desired output (shown below).
```js
[
'<li class="text-warning">no-var</li>',
'<li class="text-warning">var-on-top</li>',
'<li class="text-warning">linebreak</li>'
]
```
# --hints--
`failuresList` should be an array containing `result failure` messages.
```js
assert(
typeof makeList(result.failure) === 'object' && failuresList.length === 3
);
```
`failuresList` should be equal to the specified output.
```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>`
)
);
```
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 = {
success: ["max-length", "no-amd", "prefer-arrow-functions"],
failure: ["no-var", "var-on-top", "linebreak"],
skipped: ["no-extra-semi", "no-dup-keys"]
};
function makeList(arr) {
// Only change code below this line
const failureItems = [];
// Only change code above this line
return failureItems;
}
const failuresList = makeList(result.failure);
```
# --solutions--
```js
const result = {
success: ["max-length", "no-amd", "prefer-arrow-functions"],
failure: ["no-var", "var-on-top", "linebreak"],
skipped: ["no-extra-semi", "no-dup-keys"]
};
function makeList(arr) {
return arr.map(val => `<li class="text-warning">${val}</li>`);
}
const failuresList = makeList(result.failure);
```

View File

@ -0,0 +1,87 @@
---
id: 587d7b87367417b2b2512b41
title: Declare a Read-Only Variable with the const Keyword
challengeType: 1
forumTopicId: 301201
dashedName: declare-a-read-only-variable-with-the-const-keyword
---
# --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 `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.
**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.
# --instructions--
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));
```
`SENTENCE` should be a constant variable declared with `const`.
```js
(getUserInput) => assert(getUserInput('index').match(/(const SENTENCE)/g));
```
`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) {
// Only change code below this line
var sentence = str + " is cool!";
for (var i = 0; i < str.length; i+=2) {
console.log(sentence);
}
// Only change code above this line
}
printManyTimes("freeCodeCamp");
```
# --solutions--
```js
function printManyTimes(str) {
const SENTENCE = str + " is cool!";
for (let i = 0; i < str.length; i+=2) {
console.log(SENTENCE);
}
}
printManyTimes("freeCodeCamp");
```

View File

@ -0,0 +1,88 @@
---
id: 587d7b87367417b2b2512b3f
title: Explore Differences Between the var and let Keywords
challengeType: 1
forumTopicId: 301202
dashedName: explore-differences-between-the-var-and-let-keywords
---
# --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';
var camper = 'David';
console.log(camper);
// logs 'David'
```
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 `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
```
# --instructions--
Update the code so it only uses the `let` keyword.
# --hints--
`var` should not exist in the code.
```js
(getUserInput) => assert(!getUserInput('index').match(/var/g));
```
`catName` should be `Oliver`.
```js
assert(catName === 'Oliver');
```
`quote` should be `"Oliver says Meow!"`
```js
assert(quote === 'Oliver says Meow!');
```
# --seed--
## --seed-contents--
```js
var catName;
var quote;
function catTalk() {
"use strict";
catName = "Oliver";
quote = catName + " says Meow!";
}
catTalk();
```
# --solutions--
```js
let catName;
let quote;
function catTalk() {
'use strict';
catName = 'Oliver';
quote = catName + ' says Meow!';
}
catTalk();
```

View File

@ -0,0 +1,92 @@
---
id: 5cdafbd72913098997531681
title: Handle a Fulfilled Promise with then
challengeType: 1
forumTopicId: 301203
dashedName: handle-a-fulfilled-promise-with-then
---
# --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 => {
// do something with the result.
});
```
`result` comes from the argument given to the `resolve` method.
# --instructions--
Add the `then` method to your promise. Use `result` as the parameter of its callback function and log `result` to the console.
# --hints--
You should call the `then` method on the promise.
```js
assert(
__helpers.removeWhiteSpace(code).match(/(makeServerRequest|\))\.then\(/g)
);
```
Your `then` method should have a callback function with `result` as its parameter.
```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));
```
## --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 {
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");
}
});
makeServerRequest.then(result => {
console.log(result);
});
```

View File

@ -0,0 +1,100 @@
---
id: 5cdafbe72913098997531682
title: Handle a Rejected Promise with catch
challengeType: 1
forumTopicId: 301204
dashedName: handle-a-rejected-promise-with-catch
---
# --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 => {
// do something with the error.
});
```
`error` is the argument passed in to the `reject` method.
# --instructions--
Add the `catch` method to your promise. Use `error` as the parameter of its callback function and log `error` to the console.
# --hints--
You should call the `catch` method on the promise.
```js
assert(
__helpers.removeWhiteSpace(code).match(/(makeServerRequest|\))\.catch\(/g)
);
```
Your `catch` method should have a callback function with `error` as its parameter.
```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 {
reject("Data not received");
}
});
makeServerRequest.then(result => {
console.log(result);
});
```
# --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 {
reject("Data not received");
}
});
makeServerRequest.then(result => {
console.log(result);
});
makeServerRequest.catch(error => {
console.log(error);
});
```

View File

@ -0,0 +1,48 @@
---
id: 587d7b8d367417b2b2512b59
title: Import a Default Export
challengeType: 1
forumTopicId: 301205
dashedName: import-a-default-export
---
# --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, `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--
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`.
# --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));
```
# --seed--
## --seed-contents--
```js
// Only change code above this line
subtract(7,4);
```
# --solutions--
```js
import subtract from "./math_functions.js";
subtract(7,4);
```

View File

@ -0,0 +1,87 @@
---
id: 587d7b87367417b2b2512b42
title: Mutate an Array Declared with const
challengeType: 1
forumTopicId: 301206
dashedName: mutate-an-array-declared-with-const
---
# --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];
s = [1, 2, 3]; // throws error, trying to assign a const
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 `[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--
An array is declared as `const s = [5, 7, 2]`. Change the array to `[2, 5, 7]` using various element assignments.
# --hints--
You should not replace `const` keyword.
```js
(getUserInput) => assert(getUserInput('index').match(/const/g));
```
`s` should be a constant variable (by using `const`).
```js
(getUserInput) => assert(getUserInput('index').match(/const\s+s/g));
```
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];
function editInPlace() {
// Only change code below this line
// Using s = [2, 5, 7] would be invalid
// Only change code above this line
}
editInPlace();
```
# --solutions--
```js
const s = [5, 7, 2];
function editInPlace() {
s[0] = 2;
s[1] = 5;
s[2] = 7;
}
editInPlace();
```

View File

@ -0,0 +1,103 @@
---
id: 598f48a36c8c40764b4e52b3
title: Prevent Object Mutation
challengeType: 1
forumTopicId: 301207
dashedName: prevent-object-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
let obj = {
name:"FreeCodeCamp",
review:"Awesome"
};
Object.freeze(obj);
obj.review = "bad"; // will be ignored. Mutation not allowed
obj.newProp = "Test"; // will be ignored. Mutation not allowed
console.log(obj);
// { name: "FreeCodeCamp", review:"Awesome"}
```
# --instructions--
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.
# --hints--
You should not replace `const` keyword.
```js
(getUserInput) => assert(getUserInput('index').match(/const/g));
```
`MATH_CONSTANTS` should be a constant variable (by using `const`).
```js
(getUserInput) =>
assert(getUserInput('index').match(/const\s+MATH_CONSTANTS/g));
```
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() {
const MATH_CONSTANTS = {
PI: 3.14
};
// Only change code below this line
// Only change code above this line
try {
MATH_CONSTANTS.PI = 99;
} catch(ex) {
console.log(ex);
}
return MATH_CONSTANTS.PI;
}
const PI = freezeObj();
```
# --solutions--
```js
function freezeObj() {
const MATH_CONSTANTS = {
PI: 3.14
};
Object.freeze(MATH_CONSTANTS);
try {
MATH_CONSTANTS.PI = 99;
} catch(ex) {
console.log(ex);
}
return MATH_CONSTANTS.PI;
}
const PI = freezeObj();
```

View File

@ -0,0 +1,70 @@
---
id: 587d7b8c367417b2b2512b55
title: Reuse JavaScript Code Using import
challengeType: 1
forumTopicId: 301208
dashedName: reuse-javascript-code-using-import
---
# --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, `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 `import` statement like this:
```js
import { add, subtract } from './math_functions.js';
```
# --instructions--
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.
# --hints--
You should properly import `uppercaseString`.
```js
assert(
code.match(
/import\s*{\s*(uppercaseString[^}]*|[^,]*,\s*uppercaseString\s*)}\s+from\s+('|")\.\/string_functions\.js\2/g
)
);
```
You should properly import `lowercaseString`.
```js
assert(
code.match(
/import\s*{\s*(lowercaseString[^}]*|[^,]*,\s*lowercaseString\s*)}\s+from\s+('|")\.\/string_functions\.js\2/g
)
);
```
# --seed--
## --seed-contents--
```js
// Only change code above this line
uppercaseString("hello");
lowercaseString("WORLD!");
```
# --solutions--
```js
import { uppercaseString, lowercaseString } from './string_functions.js';
uppercaseString("hello");
lowercaseString("WORLD!");
```

View File

@ -0,0 +1,62 @@
---
id: 587d7b88367417b2b2512b46
title: Set Default Parameters for Your Functions
challengeType: 1
forumTopicId: 301209
dashedName: set-default-parameters-for-your-functions
---
# --description--
In order to help us create more flexible functions, ES6 introduces <dfn>default parameters</dfn> for functions.
Check out this code:
```js
const greeting = (name = "Anonymous") => "Hello " + name;
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 `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--
Modify the function `increment` by adding default parameters so that it will add 1 to `number` if `value` is not specified.
# --hints--
The result of `increment(5, 2)` should be `7`.
```js
assert(increment(5, 2) === 7);
```
The result of `increment(5)` should be `6`.
```js
assert(increment(5) === 6);
```
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
const increment = (number, value) => number + value;
// Only change code above this line
```
# --solutions--
```js
const increment = (number, value = 1) => number + value;
```

View File

@ -0,0 +1,59 @@
---
id: 587d7b8c367417b2b2512b57
title: Use * to Import Everything from a File
challengeType: 1
forumTopicId: 301210
dashedName: use--to-import-everything-from-a-file
---
# --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 `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);
```
# --instructions--
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`.
# --hints--
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!");
```
# --solutions--
```js
import * as stringFunctions from "./string_functions.js";
// add code above this line
stringFunctions.uppercaseString("hello");
stringFunctions.lowercaseString("WORLD!");
```

View File

@ -0,0 +1,91 @@
---
id: 587d7b87367417b2b2512b43
title: Use Arrow Functions to Write Concise Anonymous Functions
challengeType: 1
forumTopicId: 301211
dashedName: use-arrow-functions-to-write-concise-anonymous-functions
---
# --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
const myFunc = function() {
const myVar = "value";
return myVar;
}
```
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 = () => {
const myVar = "value";
return myVar;
}
```
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 `value` by default.
# --instructions--
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`.
# --hints--
User should replace `var` keyword.
```js
(getUserInput) => assert(!getUserInput('index').match(/var/g));
```
`magic` should be a constant variable (by using `const`).
```js
(getUserInput) => assert(getUserInput('index').match(/const\s+magic/g));
```
`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() {
return new Date();
};
```
# --solutions--
```js
const magic = () => {
return new Date();
};
```

View File

@ -0,0 +1,100 @@
---
id: 587d7b8b367417b2b2512b53
title: Use class Syntax to Define a Constructor Function
challengeType: 1
forumTopicId: 301212
dashedName: use-class-syntax-to-define-a-constructor-function
---
# --description--
ES6 provides a new syntax to create objects, using the <dfn>class</dfn> keyword.
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){
this.targetPlanet = targetPlanet;
}
var zeus = new SpaceShuttle('Jupiter');
```
The `class` syntax simply replaces the constructor function creation:
```js
class SpaceShuttle {
constructor(targetPlanet) {
this.targetPlanet = targetPlanet;
}
}
const zeus = new SpaceShuttle('Jupiter');
```
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:**
- 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.
# --instructions--
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'
);
```
`class` keyword should be used.
```js
assert(code.match(/class/g));
```
`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
// Only change code above this line
const carrot = new Vegetable('carrot');
console.log(carrot.name); // Should display 'carrot'
```
# --solutions--
```js
class Vegetable {
constructor(name) {
this.name = name;
}
}
const carrot = new Vegetable('carrot');
```

View File

@ -0,0 +1,67 @@
---
id: 587d7b89367417b2b2512b4b
title: Use Destructuring Assignment to Assign Variables from Arrays
challengeType: 1
forumTopicId: 301213
dashedName: use-destructuring-assignment-to-assign-variables-from-arrays
---
# --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
const [a, b] = [1, 2, 3, 4, 5, 6];
console.log(a, b); // 1, 2
```
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
```
# --instructions--
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`.
# --hints--
Value of `a` should be 6, after swapping.
```js
assert(a === 6);
```
Value of `b` should be 8, after swapping.
```js
assert(b === 8);
```
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
```
# --solutions--
```js
let a = 8, b = 6;
[a, b] = [b, a];
```

View File

@ -0,0 +1,106 @@
---
id: 587d7b89367417b2b2512b4a
title: Use Destructuring Assignment to Assign Variables from Nested Objects
challengeType: 1
forumTopicId: 301214
dashedName: use-destructuring-assignment-to-assign-variables-from-nested-objects
---
# --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:
```js
const user = {
johnDoe: {
age: 34,
email: 'johnDoe@freeCodeCamp.com'
}
};
```
Here's how to extract the values of object properties and assign them to variables with the same name:
```js
const { johnDoe: { age, email }} = user;
```
And here's how you can assign an object properties' values to variables with different names:
```js
const { johnDoe: { age: userAge, email: userEmail }} = user;
```
# --instructions--
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.
# --hints--
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)
);
```
You should use destructuring to create the `lowToday` variable.
```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 = {
yesterday: { low: 61, high: 75 },
today: { low: 64, high: 77 },
tomorrow: { low: 68, high: 80 }
};
// Only change code below this line
const lowToday = LOCAL_FORECAST.today.low;
const highToday = LOCAL_FORECAST.today.high;
// Only change code above this line
```
# --solutions--
```js
const LOCAL_FORECAST = {
yesterday: { low: 61, high: 75 },
today: { low: 64, high: 77 },
tomorrow: { low: 68, high: 80 }
};
const { today: { low: lowToday, high: highToday }} = LOCAL_FORECAST;
```

View File

@ -0,0 +1,98 @@
---
id: 587d7b89367417b2b2512b49
title: Use Destructuring Assignment to Assign Variables from Objects
challengeType: 1
forumTopicId: 301215
dashedName: use-destructuring-assignment-to-assign-variables-from-objects
---
# --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:
```js
const user = { name: 'John Doe', age: 34 };
```
Here's how you can give new variable names in the assignment:
```js
const { name: userName, age: userAge } = user;
// userName = 'John Doe', userAge = 34
```
You may read it as "get the value of `user.name` and assign it to a new variable named `userName`" and so on.
# --instructions--
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.
# --hints--
You should remove the ES5 assignment syntax.
```js
assert(
!code.match(/highToday = HIGH_TEMPERATURES\.today/g) &&
!code.match(/highTomorrow = HIGH_TEMPERATURES\.tomorrow/g)
);
```
You should use destructuring to create the `highToday` variable.
```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 = {
yesterday: 75,
today: 77,
tomorrow: 80
};
// Only change code below this line
const highToday = HIGH_TEMPERATURES.today;
const highTomorrow = HIGH_TEMPERATURES.tomorrow;
// Only change code above this line
```
# --solutions--
```js
const HIGH_TEMPERATURES = {
yesterday: 75,
today: 77,
tomorrow: 80
};
const { today: highToday, tomorrow: highTomorrow } = HIGH_TEMPERATURES;
```

View File

@ -0,0 +1,108 @@
---
id: 5cfa550e84205a357704ccb6
title: Use Destructuring Assignment to Extract Values from Objects
challengeType: 1
forumTopicId: 301216
dashedName: use-destructuring-assignment-to-extract-values-from-objects
---
# --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:
```js
const user = { name: 'John Doe', age: 34 };
const name = user.name; // name = 'John Doe'
const age = user.age; // age = 34
```
Here's an equivalent assignment statement using the ES6 destructuring syntax:
```js
const { name, age } = user;
// name = 'John Doe', age = 34
```
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.
# --instructions--
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.
# --hints--
You should remove the ES5 assignment syntax.
```js
assert(
!__helpers
.removeJSComments(code)
.match(/today\s*=\s*HIGH_TEMPERATURES\.(today|tomorrow)/g)
);
```
You should use destructuring to create the `today` variable.
```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 = {
yesterday: 75,
today: 77,
tomorrow: 80
};
// Only change code below this line
const today = HIGH_TEMPERATURES.today;
const tomorrow = HIGH_TEMPERATURES.tomorrow;
// Only change code above this line
```
# --solutions--
```js
const HIGH_TEMPERATURES = {
yesterday: 75,
today: 77,
tomorrow: 80
};
const { today, tomorrow } = HIGH_TEMPERATURES;
```

View File

@ -0,0 +1,94 @@
---
id: 587d7b8a367417b2b2512b4d
title: Use Destructuring Assignment to Pass an Object as a Function's Parameters
challengeType: 1
forumTopicId: 301217
dashedName: use-destructuring-assignment-to-pass-an-object-as-a-functions-parameters
---
# --description--
In some cases, you can destructure the object in a function argument itself.
Consider the code below:
```js
const profileUpdate = (profileData) => {
const { name, age, nationality, location } = profileData;
// do something with these variables
}
```
This effectively destructures the object sent into the function. This can also be done in-place:
```js
const profileUpdate = ({ name, age, nationality, location }) => {
/* do something with these fields */
}
```
When `profileData` is passed to the above function, the values are destructured from the function parameter for use within the function.
# --instructions--
Use destructuring assignment within the argument to the function `half` to send only `max` and `min` inside the function.
# --hints--
`stats` should be an `object`.
```js
assert(typeof stats === 'object');
```
`half(stats)` should be `28.015`
```js
assert(half(stats) === 28.015);
```
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 = {
max: 56.78,
standard_deviation: 4.34,
median: 34.54,
mode: 23.87,
min: -0.75,
average: 35.85
};
// Only change code below this line
const half = (stats) => (stats.max + stats.min) / 2.0;
// Only change code above this line
```
# --solutions--
```js
const stats = {
max: 56.78,
standard_deviation: 4.34,
median: 34.54,
mode: 23.87,
min: -0.75,
average: 35.85
};
const half = ( {max, min} ) => (max + min) / 2.0;
```

View File

@ -0,0 +1,83 @@
---
id: 587d7b8a367417b2b2512b4c
title: >-
Use Destructuring Assignment with the Rest Parameter to Reassign Array Elements
challengeType: 1
forumTopicId: 301218
dashedName: >-
use-destructuring-assignment-with-the-rest-parameter-to-reassign-array-elements
---
# --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 `Array.prototype.slice()`, as shown below:
```js
const [a, b, ...arr] = [1, 2, 3, 4, 5, 7];
console.log(a, b); // 1, 2
console.log(arr); // [3, 4, 5, 7]
```
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--
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.
# --hints--
`arr` should be `[3,4,5,6,7,8,9,10]`
```js
assert(arr.every((v, i) => v === i + 3) && arr.length === 8);
```
`source` should be `[1,2,3,4,5,6,7,8,9,10]`
```js
assert(source.every((v, i) => v === i + 1) && source.length === 10);
```
`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];
function removeFirstTwo(list) {
// Only change code below this line
const arr = list; // Change this line
// Only change code above this line
return arr;
}
const arr = removeFirstTwo(source);
```
# --solutions--
```js
const source = [1,2,3,4,5,6,7,8,9,10];
function removeFirstTwo(list) {
const [, , ...arr] = list;
return arr;
}
const arr = removeFirstTwo(source);
```

View File

@ -0,0 +1,85 @@
---
id: 587d7b8c367417b2b2512b56
title: Use export to Share a Code Block
challengeType: 1
forumTopicId: 301219
dashedName: use-export-to-share-a-code-block
---
# --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) => {
return x + y;
}
```
The above is a common way to export a single function, but you can achieve the same thing like this:
```js
const add = (x, y) => {
return x + y;
}
export { add };
```
When you export a variable or function, you can import it in another file and use it without having to rewrite the code. You can export multiple things by repeating the first example for each thing you want to export, or by placing them all in the export statement of the second example, like this:
```js
export { add, subtract };
```
# --instructions--
There are two string-related functions in the editor. Export both of them using the method of your choice.
# --hints--
You should properly export `uppercaseString`.
```js
assert(
code.match(
/(export\s+const\s+uppercaseString|export\s*{\s*(uppercaseString[^}]*|[^,]*,\s*uppercaseString\s*)})/g
)
);
```
You should properly export `lowercaseString`.
```js
assert(
code.match(
/(export\s+const\s+lowercaseString|export\s*{\s*(lowercaseString[^}]*|[^,]*,\s*lowercaseString\s*)})/g
)
);
```
# --seed--
## --seed-contents--
```js
const uppercaseString = (string) => {
return string.toUpperCase();
}
const lowercaseString = (string) => {
return string.toLowerCase()
}
```
# --solutions--
```js
export const uppercaseString = (string) => {
return string.toUpperCase();
}
export const lowercaseString = (string) => {
return string.toLowerCase()
}
```

View File

@ -0,0 +1,170 @@
---
id: 587d7b8c367417b2b2512b54
title: Use getters and setters to Control Access to an Object
challengeType: 1
forumTopicId: 301220
dashedName: use-getters-and-setters-to-control-access-to-an-object
---
# --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.
```js
class Book {
constructor(author) {
this._author = author;
}
// getter
get writer() {
return this._author;
}
// setter
set writer(updatedAuthor) {
this._author = updatedAuthor;
}
}
const novel = new Book('anonymous');
console.log(novel.writer); // anonymous
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. **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.
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.
# --hints--
`Thermostat` should be a `class` with a defined `constructor` method.
```js
assert(
typeof Thermostat === 'function' &&
typeof Thermostat.constructor === 'function'
);
```
`class` keyword should be used.
```js
assert(code.match(/class/g));
```
`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
// Only change code above this line
const thermos = new Thermostat(76); // Setting in Fahrenheit scale
let temp = thermos.temperature; // 24.44 in Celsius
thermos.temperature = 26;
temp = thermos.temperature; // 26 in Celsius
```
# --solutions--
```js
class Thermostat {
constructor(fahrenheit) {
this._tempInCelsius = 5/9 * (fahrenheit - 32);
}
get temperature(){
return this._tempInCelsius;
}
set temperature(newTemp){
this._tempInCelsius = newTemp;
}
}
const thermos = new Thermostat(76); // Setting in Fahrenheit scale
let temp = thermos.temperature; // 24.44 in Celsius
thermos.temperature = 26;
temp = thermos.temperature; // 26 in Celsius
```

View File

@ -0,0 +1,78 @@
---
id: 587d7b88367417b2b2512b47
title: Use the Rest Parameter with Function Parameters
challengeType: 1
forumTopicId: 301221
dashedName: use-the-rest-parameter-with-function-parameters
---
# --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
function howMany(...args) {
return "You have passed " + args.length + " arguments.";
}
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 `args` array and allows us to apply `map()`, `filter()` and `reduce()` on the parameters array.
# --instructions--
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.
# --hints--
The result of `sum(0,1,2)` should be 3
```js
assert(sum(0, 1, 2) === 3);
```
The result of `sum(1,2,3,4)` should be 10
```js
assert(sum(1, 2, 3, 4) === 10);
```
The result of `sum(5)` should be 5
```js
assert(sum(5) === 5);
```
The result of `sum()` should be 0
```js
assert(sum() === 0);
```
`sum` should be an arrow function which uses the rest parameter syntax (`...`) on the `args` parameter.
```js
assert(__helpers.removeWhiteSpace(code).match(/sum=\(\.\.\.args\)=>/));
```
# --seed--
## --seed-contents--
```js
const sum = (x, y, z) => {
const args = [x, y, z];
return args.reduce((a, b) => a + b, 0);
}
```
# --solutions--
```js
const sum = (...args) => {
return args.reduce((a, b) => a + b, 0);
}
```

View File

@ -0,0 +1,80 @@
---
id: 587d7b89367417b2b2512b48
title: Use the Spread Operator to Evaluate Arrays In-Place
challengeType: 1
forumTopicId: 301222
dashedName: use-the-spread-operator-to-evaluate-arrays-in-place
---
# --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 `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 `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
```
`...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
```
# --instructions--
Copy all contents of `arr1` into another array `arr2` using the spread operator.
# --hints--
`arr2` should be correct copy of `arr1`.
```js
assert(arr2.every((v, i) => v === arr1[i]) && arr2.length);
```
`...` spread operator should be used to duplicate `arr1`.
```js
assert(code.match(/Array\(\s*\.\.\.arr1\s*\)|\[\s*\.\.\.arr1\s*\]/));
```
`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'];
let arr2;
arr2 = []; // Change this line
console.log(arr2);
```
# --solutions--
```js
const arr1 = ['JAN', 'FEB', 'MAR', 'APR', 'MAY'];
let arr2;
arr2 = [...arr1];
```

View File

@ -0,0 +1,93 @@
---
id: 587d7b88367417b2b2512b44
title: Write Arrow Functions with Parameters
challengeType: 1
forumTopicId: 301223
dashedName: write-arrow-functions-with-parameters
---
# --description--
Just like a regular function, you can pass arguments into an arrow function.
```js
// doubles input value and returns it
const doubler = (item) => item * 2;
doubler(4); // returns 8
```
If an arrow function has a single parameter, the parentheses enclosing the parameter may be omitted.
```js
// the same function, without the parameter parentheses
const doubler = item => item * 2;
```
It is possible to pass more than one argument into an arrow function.
```js
// multiplies the first input value by the second and returns it
const multiplier = (item, multi) => item * multi;
multiplier(4, 2); // returns 8
```
# --instructions--
Rewrite the `myConcat` function which appends contents of `arr2` to `arr1` so that the function uses arrow function syntax.
# --hints--
You should replace the `var` keyword.
```js
(getUserInput) => assert(!getUserInput('index').match(/var/g));
```
`myConcat` should be a constant variable (by using `const`).
```js
(getUserInput) => assert(getUserInput('index').match(/const\s+myConcat/g));
```
`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) {
return arr1.concat(arr2);
};
console.log(myConcat([1, 2], [3, 4, 5]));
```
# --solutions--
```js
const myConcat = (arr1, arr2) => {
return arr1.concat(arr2);
};
console.log(myConcat([1, 2], [3, 4, 5]));
```

View File

@ -0,0 +1,86 @@
---
id: 587d7b8b367417b2b2512b50
title: Write Concise Declarative Functions with ES6
challengeType: 1
forumTopicId: 301224
dashedName: write-concise-declarative-functions-with-es6
---
# --description--
When defining functions within objects in ES5, we have to use the keyword `function` as follows:
```js
const person = {
name: "Taylor",
sayHello: function() {
return `Hello! My name is ${this.name}.`;
}
};
```
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 = {
name: "Taylor",
sayHello() {
return `Hello! My name is ${this.name}.`;
}
};
```
# --instructions--
Refactor the function `setGear` inside the object `bicycle` to use the shorthand syntax described above.
# --hints--
Traditional function expression should not be used.
```js
(getUserInput) => assert(!__helpers.removeJSComments(code).match(/function/));
```
`setGear` should be a declarative function.
```js
assert(
typeof bicycle.setGear === 'function' && code.match(/setGear\s*\(.+\)\s*\{/)
);
```
`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
const bicycle = {
gear: 2,
setGear: function(newGear) {
this.gear = newGear;
}
};
// Only change code above this line
bicycle.setGear(3);
console.log(bicycle.gear);
```
# --solutions--
```js
const bicycle = {
gear: 2,
setGear(newGear) {
this.gear = newGear;
}
};
bicycle.setGear(3);
```

View File

@ -0,0 +1,75 @@
---
id: 587d7b8a367417b2b2512b4f
title: Write Concise Object Literal Declarations Using Object Property Shorthand
challengeType: 1
forumTopicId: 301225
dashedName: write-concise-object-literal-declarations-using-object-property-shorthand
---
# --description--
ES6 adds some nice support for easily defining object literals.
Consider the following code:
```js
const getMousePosition = (x, y) => ({
x: x,
y: y
});
```
`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 });
```
# --instructions--
Use object property shorthand with object literals to create and return an object with `name`, `age` and `gender` properties.
# --hints--
`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')
);
```
Your code should not use `key:value`.
```js
(getUserInput) => assert(!getUserInput('index').match(/:/g));
```
# --seed--
## --seed-contents--
```js
const createPerson = (name, age, gender) => {
// Only change code below this line
return {
name: name,
age: age,
gender: gender
};
// Only change code above this line
};
```
# --solutions--
```js
const createPerson = (name, age, gender) => {
return {
name,
age,
gender
};
};
```