fix(curriculum): Convert blockquote elements to triple backtick syntax for JavaScript Algorithms and Data Structures (#35992)
* fix: convert js algorithms and data structures * fix: revert some blocks back to blockquote * fix: reverted comparison code block to blockquotes * fix: change js to json Co-Authored-By: Oliver Eyton-Williams <ojeytonwilliams@gmail.com> * fix: convert various section to triple backticks * fix: Make the formatting consistent for comparisons
This commit is contained in:
@ -9,13 +9,65 @@ challengeType: 1
|
||||
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.
|
||||
For example:
|
||||
<blockquote>var numArray = [];<br>for (var i = 0; i < 3; i++) {<br> numArray.push(i);<br>}<br>console.log(numArray);<br>// returns [0, 1, 2]<br>console.log(i);<br>// returns 3</blockquote>
|
||||
|
||||
```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 <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:
|
||||
<blockquote>var numArray = [];<br>var i;<br>for (i = 0; i < 3; i++) {<br> numArray.push(i);<br>}<br>console.log(numArray);<br>// returns [0, 1, 2]<br>console.log(i);<br>// returns 3</blockquote>
|
||||
|
||||
```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 <code>i</code> variable. This is because the stored function will always refer to the value of the updated global <code>i</code> variable.
|
||||
<blockquote>var printNumTwo;<br>for (var i = 0; i < 3; i++) {<br> if (i === 2) {<br> printNumTwo = function() {<br> return i;<br> };<br> }<br>}<br>console.log(printNumTwo());<br>// returns 3</blockquote>
|
||||
|
||||
```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, <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:
|
||||
<blockquote>'use strict';<br>let printNumTwo;<br>for (let i = 0; i < 3; i++) {<br> if (i === 2) {<br> printNumTwo = function() {<br> return i;<br> };<br> }<br>}<br>console.log(printNumTwo());<br>// returns 2<br>console.log(i);<br>// returns "i is not defined"</blockquote>
|
||||
|
||||
```js
|
||||
'use strict';
|
||||
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"
|
||||
```
|
||||
|
||||
<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>
|
||||
|
||||
|
@ -9,7 +9,13 @@ challengeType: 1
|
||||
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.
|
||||
Here is a quick example of <code>export default</code>:
|
||||
<blockquote>export default function add(x,y) {<br> return x + y;<br>}</blockquote>
|
||||
|
||||
```js
|
||||
export default function add(x,y) {
|
||||
return x + y;
|
||||
}
|
||||
```
|
||||
|
||||
Note: 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>
|
||||
|
||||
|
@ -9,7 +9,23 @@ challengeType: 1
|
||||
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:
|
||||
<blockquote>const person = {<br> name: "Zodiac Hasbro",<br> age: 56<br>};<br><br>// Template literal with multi-line and string interpolation<br>const greeting = `Hello, my name is ${person.name}!<br>I am ${person.age} years old.`;<br><br>console.log(greeting); // prints<br>// Hello, my name is Zodiac Hasbro!<br>// I am 56 years old.<br></blockquote>
|
||||
|
||||
```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 (<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.
|
||||
|
@ -8,7 +8,13 @@ challengeType: 1
|
||||
<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.
|
||||
<blockquote>"use strict";<br>const FAV_PET = "Cats";<br>FAV_PET = "Dogs"; // returns error</blockquote>
|
||||
|
||||
```js
|
||||
"use strict";
|
||||
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.
|
||||
|
@ -7,17 +7,34 @@ challengeType: 1
|
||||
## 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.
|
||||
<blockquote>var camper = 'James';<br>var camper = 'David';<br>console.log(camper);<br>// logs 'David'</blockquote>
|
||||
|
||||
```js
|
||||
var camper = 'James';
|
||||
var camper = 'David';
|
||||
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.
|
||||
<blockquote>let camper = 'James';<br>let camper = 'David'; // throws an error</blockquote>
|
||||
|
||||
```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:
|
||||
<blockquote>"use strict";<br>x = 3.14; // throws an error because x is not declared</blockquote>
|
||||
|
||||
```js
|
||||
"use strict";
|
||||
x = 3.14; // throws an error because x is not declared
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
|
@ -8,7 +8,12 @@ challengeType: 1
|
||||
<section id='description'>
|
||||
In the last challenge, you learned about <code>export default</code> and its uses. It is important to note that, to import a default export, you need to use a different <code>import</code> syntax.
|
||||
In the following example, we have a function, <code>add</code>, that is the default export of a file, <code>"math_functions"</code>. Here is how to import it:
|
||||
<blockquote>import add from "math_functions";<br>add(5,4); // Will return 9</blockquote>
|
||||
|
||||
```js
|
||||
import add from "math_functions";
|
||||
add(5,4); // Will return 9
|
||||
```
|
||||
|
||||
The syntax differs in one key place - the imported value, <code>add</code>, is not surrounded by curly braces, <code>{}</code>. Unlike exported values, the primary method of importing a default export is to simply write the value's name after <code>import</code>.
|
||||
</section>
|
||||
|
||||
|
@ -9,7 +9,15 @@ challengeType: 1
|
||||
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.
|
||||
<blockquote>"use strict";<br>const s = [5, 6, 7];<br>s = [1, 2, 3]; // throws error, trying to assign a const<br>s[2] = 45; // works just as it would with an array declared with var or let<br>console.log(s); // returns [5, 6, 45]</blockquote>
|
||||
|
||||
```js
|
||||
"use strict";
|
||||
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 <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>
|
||||
|
||||
|
@ -8,7 +8,19 @@ challengeType: 1
|
||||
<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.
|
||||
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.
|
||||
<blockquote>let obj = {<br> name:"FreeCodeCamp",<br> review:"Awesome"<br>};<br>Object.freeze(obj);<br>obj.review = "bad"; // will be ignored. Mutation not allowed<br>obj.newProp = "Test"; // will be ignored. Mutation not allowed<br>console.log(obj); <br>// { name: "FreeCodeCamp", review:"Awesome"}</blockquote>
|
||||
|
||||
```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"}
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
|
@ -8,7 +8,15 @@ challengeType: 1
|
||||
<section id='description'>
|
||||
In order to help us create more flexible functions, ES6 introduces <dfn>default parameters</dfn> for functions.
|
||||
Check out this code:
|
||||
<blockquote>function greeting(name = "Anonymous") {<br> return "Hello " + name;<br>}<br>console.log(greeting("John")); // Hello John<br>console.log(greeting()); // Hello Anonymous</blockquote>
|
||||
|
||||
```js
|
||||
function greeting(name = "Anonymous") {
|
||||
return "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 <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>
|
||||
|
||||
|
@ -9,9 +9,18 @@ challengeType: 1
|
||||
In the past, the function <code>require()</code> would be used to import the functions and code in external files and modules. While handy, this presents a problem: some files and modules are rather large, and you may only need certain code from those external resources.
|
||||
ES6 gives us a very handy tool known as <dfn>import</dfn>. With it, we can choose which parts of a module or file to load into a given file, saving time and memory.
|
||||
Consider the following example. Imagine that <code>math_array_functions</code> has about 20 functions, but I only need one, <code>countItems</code>, in my current file. The old <code>require()</code> approach would force me to bring in all 20 functions. With this new <code>import</code> syntax, I can bring in just the desired function, like so:
|
||||
<blockquote>import { countItems } from "math_array_functions"</blockquote>
|
||||
|
||||
```js
|
||||
import { countItems } from "math_array_functions"
|
||||
```
|
||||
|
||||
A description of the above code:
|
||||
<blockquote>import { function } from "file_path_goes_here"<br>// We can also import variables the same way!</blockquote>
|
||||
|
||||
```js
|
||||
import { function } from "file_path_goes_here"
|
||||
// We can also import variables the same way!
|
||||
```
|
||||
|
||||
There are a few ways to write an <code>import</code> statement, but the above is a very common use-case.
|
||||
<strong>Note</strong><br>The whitespace surrounding the function inside the curly braces is a best practice - it makes it easier to read the <code>import</code> statement.
|
||||
<strong>Note</strong><br>The lessons in this section handle non-browser features. <code>import</code>, and the statements we introduce in the rest of these lessons, won't work on a browser directly. However, we can use various tools to create code out of this to make it work in browser.
|
||||
|
@ -8,9 +8,20 @@ challengeType: 1
|
||||
<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"</code> are imported into a file in the same directory:
|
||||
<blockquote>import * as myMathModule from "math_functions";<br>myMathModule.add(2,3);<br>myMathModule.subtract(5,3);</blockquote>
|
||||
|
||||
```js
|
||||
import * as myMathModule from "math_functions";
|
||||
myMathModule.add(2,3);
|
||||
myMathModule.subtract(5,3);
|
||||
```
|
||||
|
||||
And breaking down that code:
|
||||
<blockquote>import * as object_with_name_of_your_choice from "file_path_goes_here"<br>object_with_name_of_your_choice.imported_function</blockquote>
|
||||
|
||||
```js
|
||||
import * as object_with_name_of_your_choice from "file_path_goes_here"
|
||||
object_with_name_of_your_choice.imported_function
|
||||
```
|
||||
|
||||
You may use any name following the <code>import * as </code>portion of the statement. In order to utilize this method, it requires an object that receives the imported values (i.e., you must provide a name). From here, you will use the dot notation to call your imported values.
|
||||
</section>
|
||||
|
||||
|
@ -8,11 +8,29 @@ challengeType: 1
|
||||
<section id='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:
|
||||
<blockquote>const myFunc = function() {<br> const myVar = "value";<br> return myVar;<br>}</blockquote>
|
||||
|
||||
```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 <strong>arrow function syntax</strong>:
|
||||
<blockquote>const myFunc = () => {<br> const myVar = "value";<br> return myVar;<br>}</blockquote>
|
||||
|
||||
```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 <code>return</code> as well as the brackets surrounding the code. This helps simplify smaller functions into one-line statements:
|
||||
<blockquote>const myFunc = () => "value"</blockquote>
|
||||
|
||||
```js
|
||||
const myFunc = () => "value"
|
||||
```
|
||||
|
||||
This code will still return <code>value</code> by default.
|
||||
</section>
|
||||
|
||||
|
@ -9,9 +9,25 @@ challengeType: 1
|
||||
ES6 provides a new syntax to help create objects, using the keyword <dfn>class</dfn>.
|
||||
This is to be noted, that the <code>class</code> syntax is just a syntax, and not a full-fledged class based implementation of object oriented paradigm, unlike in languages like Java, or Python, or Ruby etc.
|
||||
In ES5, we usually define a constructor function, and use the <code>new</code> keyword to instantiate an object.
|
||||
<blockquote>var SpaceShuttle = function(targetPlanet){<br> this.targetPlanet = targetPlanet;<br>}<br>var zeus = new SpaceShuttle('Jupiter');</blockquote>
|
||||
|
||||
```js
|
||||
var SpaceShuttle = function(targetPlanet){
|
||||
this.targetPlanet = targetPlanet;
|
||||
}
|
||||
var zeus = new SpaceShuttle('Jupiter');
|
||||
```
|
||||
|
||||
The class syntax simply replaces the constructor function creation:
|
||||
<blockquote>class SpaceShuttle {<br> constructor(targetPlanet) {<br> this.targetPlanet = targetPlanet;<br> }<br>}<br>const zeus = new SpaceShuttle('Jupiter');</blockquote>
|
||||
|
||||
```js
|
||||
class SpaceShuttle {
|
||||
constructor(targetPlanet) {
|
||||
this.targetPlanet = targetPlanet;
|
||||
}
|
||||
}
|
||||
const zeus = new SpaceShuttle('Jupiter');
|
||||
```
|
||||
|
||||
Notice that the <code>class</code> keyword declares a new function, and a constructor was added, which would be 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>
|
||||
|
@ -9,10 +9,20 @@ challengeType: 1
|
||||
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:
|
||||
<blockquote>const [a, b] = [1, 2, 3, 4, 5, 6];<br>console.log(a, b); // 1, 2</blockquote>
|
||||
|
||||
```js
|
||||
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:
|
||||
<blockquote>const [a, b,,, c] = [1, 2, 3, 4, 5, 6];<br>console.log(a, b, c); // 1, 2, 5 </blockquote>
|
||||
|
||||
```js
|
||||
const [a, b,,, c] = [1, 2, 3, 4, 5, 6];
|
||||
console.log(a, b, c); // 1, 2, 5
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
|
@ -8,7 +8,16 @@ challengeType: 1
|
||||
<section id='description'>
|
||||
We can similarly destructure <em>nested</em> objects into variables.
|
||||
Consider the following code:
|
||||
<blockquote>const a = {<br> start: { x: 5, y: 6 },<br> end: { x: 6, y: -9 }<br>};<br>const { start: { x: startX, y: startY }} = a;<br>console.log(startX, startY); // 5, 6</blockquote>
|
||||
|
||||
```js
|
||||
const a = {
|
||||
start: { x: 5, y: 6 },
|
||||
end: { x: 6, y: -9 }
|
||||
};
|
||||
const { start: { x: startX, y: startY }} = a;
|
||||
console.log(startX, startY); // 5, 6
|
||||
```
|
||||
|
||||
In the example above, the variable <code>startX</code> is assigned the value of <code>a.start.x</code>.
|
||||
</section>
|
||||
|
||||
|
@ -9,11 +9,26 @@ challengeType: 1
|
||||
We saw earlier how spread operator can effectively spread, or unpack, the contents of the array.
|
||||
We can do something similar with objects as well. <dfn>Destructuring assignment</dfn> is special syntax for neatly assigning values taken directly from an object to variables.
|
||||
Consider the following ES5 code:
|
||||
<blockquote>var voxel = { x: 3.6, y: 7.4, z: 6.54 };<br>var x = voxel.x; // x = 3.6<br>var y = voxel.y; // y = 7.4<br>var z = voxel.z; // z = 6.54</blockquote>
|
||||
|
||||
```js
|
||||
var voxel = { x: 3.6, y: 7.4, z: 6.54 };
|
||||
var x = voxel.x; // x = 3.6
|
||||
var y = voxel.y; // y = 7.4
|
||||
var z = voxel.z; // z = 6.54
|
||||
```
|
||||
|
||||
Here's the same assignment statement with ES6 destructuring syntax:
|
||||
<blockquote>const { x, y, z } = voxel; // x = 3.6, y = 7.4, z = 6.54</blockquote>
|
||||
|
||||
```js
|
||||
const { x, y, z } = voxel; // x = 3.6, y = 7.4, z = 6.54
|
||||
```
|
||||
|
||||
If instead you want to store the values of <code>voxel.x</code> into <code>a</code>, <code>voxel.y</code> into <code>b</code>, and <code>voxel.z</code> into <code>c</code>, you have that freedom as well.
|
||||
<blockquote>const { x: a, y: b, z: c } = voxel; // a = 3.6, b = 7.4, c = 6.54</blockquote>
|
||||
|
||||
```js
|
||||
const { x: a, y: b, z: c } = voxel; // a = 3.6, b = 7.4, c = 6.54
|
||||
```
|
||||
|
||||
You may read it as "get the field <code>x</code> and copy the value into <code>a</code>," and so on.
|
||||
</section>
|
||||
|
||||
|
@ -8,9 +8,22 @@ challengeType: 1
|
||||
<section id='description'>
|
||||
In some cases, you can destructure the object in a function argument itself.
|
||||
Consider the code below:
|
||||
<blockquote>const profileUpdate = (profileData) => {<br> const { name, age, nationality, location } = profileData;<br> // do something with these variables<br>}</blockquote>
|
||||
|
||||
```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:
|
||||
<blockquote>const profileUpdate = ({ name, age, nationality, location }) => {<br> /* do something with these fields */<br>}</blockquote>
|
||||
|
||||
```js
|
||||
const profileUpdate = ({ name, age, nationality, location }) => {
|
||||
/* do something with these fields */
|
||||
}
|
||||
```
|
||||
|
||||
This removes some extra lines and makes our code look neat.
|
||||
This has the added benefit of not having to manipulate an entire object in a function; only the fields that are needed are copied inside the function.
|
||||
</section>
|
||||
|
@ -8,7 +8,13 @@ challengeType: 1
|
||||
<section id='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:
|
||||
<blockquote>const [a, b, ...arr] = [1, 2, 3, 4, 5, 7];<br>console.log(a, b); // 1, 2<br>console.log(arr); // [3, 4, 5, 7]</blockquote>
|
||||
|
||||
```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 <code>a</code> and <code>b</code> take the first and second values from the array. After that, because of rest parameter's presence, <code>arr</code> gets 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 last element of the original array.
|
||||
</section>
|
||||
|
@ -8,9 +8,25 @@ challengeType: 1
|
||||
<section id='description'>
|
||||
In the previous challenge, you learned about <code>import</code> and how it can be leveraged to import small amounts of code from large files. In order for this to work, though, we must utilize one of the statements that goes with <code>import</code>, known as <dfn>export</dfn>. When we want some code - a function, or a variable - to be usable in another file, we must export it in order to import it into another file. Like <code>import</code>, <code>export</code> is a non-browser feature.
|
||||
The following is what we refer to as a <dfn>named export</dfn>. With this, we can import any code we export into another file with the <code>import</code> syntax you learned in the last lesson. Here's an example:
|
||||
<blockquote>const capitalizeString = (string) => {<br> return string.charAt(0).toUpperCase() + string.slice(1);<br>}<br>export { capitalizeString } // How to export functions.<br>export const foo = "bar"; // How to export variables.</blockquote>
|
||||
|
||||
```js
|
||||
const capitalizeString = (string) => {
|
||||
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||
}
|
||||
export { capitalizeString } // How to export functions.
|
||||
export const foo = "bar"; // How to export variables.
|
||||
```
|
||||
|
||||
Alternatively, if you would like to compact all your <code>export</code> statements into one line, you can take this approach:
|
||||
<blockquote>const capitalizeString = (string) => {<br> return string.charAt(0).toUpperCase() + string.slice(1);<br>}<br>const foo = "bar";<br>export { capitalizeString, foo }</blockquote>
|
||||
|
||||
```js
|
||||
const capitalizeString = (string) => {
|
||||
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||
}
|
||||
const foo = "bar";
|
||||
export { capitalizeString, foo }
|
||||
```
|
||||
|
||||
Either approach is perfectly acceptable.
|
||||
</section>
|
||||
|
||||
|
@ -10,7 +10,27 @@ You can obtain values from an object, and set a value of a property within an ob
|
||||
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>
|
||||
<blockquote>class Book {<br> constructor(author) {<br> this._author = author;<br> }<br> // getter<br> get writer() {<br> return this._author;<br> }<br> // setter<br> set writer(updatedAuthor) {<br> this._author = updatedAuthor;<br> }<br>}<br>const lol = new Book('anonymous');<br>console.log(lol.writer); // anonymous<br>lol.writer = 'wut';<br>console.log(lol.writer); // wut</blockquote>
|
||||
|
||||
```js
|
||||
class Book {
|
||||
constructor(author) {
|
||||
this._author = author;
|
||||
}
|
||||
// getter
|
||||
get writer() {
|
||||
return this._author;
|
||||
}
|
||||
// setter
|
||||
set writer(updatedAuthor) {
|
||||
this._author = updatedAuthor;
|
||||
}
|
||||
}
|
||||
const lol = new Book('anonymous');
|
||||
console.log(lol.writer); // anonymous
|
||||
lol.writer = 'wut';
|
||||
console.log(lol.writer); // wut
|
||||
```
|
||||
|
||||
Notice the syntax we are using to invoke the getter and setter - as if they are not even functions.
|
||||
Getters and setters are important, because they hide internal implementation details.
|
||||
<strong>Note:</strong> It is a convention to precede the name of a private variable with an underscore (<code>_</code>). The practice itself does not make a variable private.
|
||||
|
@ -8,7 +8,15 @@ challengeType: 1
|
||||
<section id='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:
|
||||
<blockquote>function howMany(...args) {<br> return "You have passed " + args.length + " arguments.";<br>}<br>console.log(howMany(0, 1, 2)); // You have passed 3 arguments<br>console.log(howMany("string", null, [1, 2, 3], { })); // You have passed 4 arguments.</blockquote>
|
||||
|
||||
```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 <code>args</code> array and allows us to apply <code>map()</code>, <code>filter()</code> and <code>reduce()</code> on the parameters array.
|
||||
</section>
|
||||
|
||||
|
@ -8,13 +8,27 @@ challengeType: 1
|
||||
<section id='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:
|
||||
<blockquote>var arr = [6, 89, 3, 45];<br>var maximus = Math.max.apply(null, arr); // returns 89</blockquote>
|
||||
|
||||
```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.
|
||||
<blockquote>const arr = [6, 89, 3, 45];<br>const maximus = Math.max(...arr); // returns 89</blockquote>
|
||||
|
||||
```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:
|
||||
<blockquote>const spreaded = ...arr; // will throw a syntax error</blockquote>
|
||||
|
||||
```js
|
||||
const spreaded = ...arr; // will throw a syntax error
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
|
@ -7,11 +7,26 @@ challengeType: 1
|
||||
## Description
|
||||
<section id='description'>
|
||||
Just like a regular function, you can pass arguments into an arrow function.
|
||||
<blockquote>// doubles input value and returns it<br>const doubler = (item) => item * 2;</blockquote>
|
||||
|
||||
```js
|
||||
// doubles input value and returns it
|
||||
const doubler = (item) => item * 2;
|
||||
```
|
||||
|
||||
If an arrow function has a single argument, the parentheses enclosing the argument may be omitted.
|
||||
<blockquote>// the same function, without the argument parentheses<br>const doubler = item => item * 2;</blockquote>
|
||||
|
||||
```js
|
||||
// the same function, without the argument parentheses
|
||||
const doubler = item => item * 2;
|
||||
```
|
||||
|
||||
It is possible to pass more than one argument into an arrow function.
|
||||
<blockquote>// multiplies the first input value by the second and returns it<br>const multiplier = (item, multi) => item * multi;</blockquote>
|
||||
|
||||
```js
|
||||
// multiplies the first input value by the second and returns it
|
||||
const multiplier = (item, multi) => item * multi;
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
|
@ -7,9 +7,27 @@ challengeType: 1
|
||||
## Description
|
||||
<section id='description'>
|
||||
When defining functions within objects in ES5, we have to use the keyword <code>function</code> as follows:
|
||||
<blockquote>const person = {<br> name: "Taylor",<br> sayHello: function() {<br> return `Hello! My name is ${this.name}.`;<br> }<br>};</blockquote>
|
||||
|
||||
```js
|
||||
const person = {
|
||||
name: "Taylor",
|
||||
sayHello: function() {
|
||||
return `Hello! My name is ${this.name}.`;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
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:
|
||||
<blockquote>const person = {<br> name: "Taylor",<br> sayHello() {<br> return `Hello! My name is ${this.name}.`;<br> }<br>};</blockquote>
|
||||
|
||||
```js
|
||||
const person = {
|
||||
name: "Taylor",
|
||||
sayHello() {
|
||||
return `Hello! My name is ${this.name}.`;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
|
@ -8,11 +8,22 @@ challengeType: 1
|
||||
<section id='description'>
|
||||
ES6 adds some nice support for easily defining object literals.
|
||||
Consider the following code:
|
||||
<blockquote>const getMousePosition = (x, y) => ({<br> x: x,<br> y: y<br>});</blockquote>
|
||||
|
||||
```js
|
||||
const getMousePosition = (x, y) => ({
|
||||
x: x,
|
||||
y: y
|
||||
});
|
||||
```
|
||||
|
||||
<code>getMousePosition</code> is a simple function that returns an object containing two fields.
|
||||
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:
|
||||
<blockquote>const getMousePosition = (x, y) => ({ x, y });</blockquote>
|
||||
|
||||
```js
|
||||
const getMousePosition = (x, y) => ({ x, y });
|
||||
```
|
||||
|
||||
</section>
|
||||
|
||||
## Instructions
|
||||
|
Reference in New Issue
Block a user