diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/access-array-data-with-indexes.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/access-array-data-with-indexes.english.md
index b4661502a4..89c51dc5b0 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/access-array-data-with-indexes.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/access-array-data-with-indexes.english.md
@@ -11,7 +11,13 @@ We can access the data inside arrays using indexes
.
Array indexes are written in the same bracket notation that strings use, except that instead of specifying a character, they are specifying an entry in the array. Like strings, arrays use zero-based indexing, so the first element in an array is element 0
.
Example
-
var array = [50,60,70];+ +```js +var array = [50,60,70]; +array[0]; // equals 50 +var data = array[1]; // equals 60 +``` + Note
array[0]; // equals 50
var data = array[1]; // equals 60
array [0]
. Although JavaScript is able to process this correctly, this may confuse other programmers reading your code.
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/access-multi-dimensional-arrays-with-indexes.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/access-multi-dimensional-arrays-with-indexes.english.md
index 802e0742f2..e160d20b9b 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/access-multi-dimensional-arrays-with-indexes.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/access-multi-dimensional-arrays-with-indexes.english.md
@@ -9,7 +9,19 @@ videoUrl: 'https://scrimba.com/c/ckND4Cq'
var arr = [+ +```js +var arr = [ + [1,2,3], + [4,5,6], + [7,8,9], + [[10,11,12], 13, 14] +]; +arr[3]; // equals [[10,11,12], 13, 14] +arr[3][0]; // equals [10,11,12] +arr[3][0][1]; // equals 11 +``` + Note
[1,2,3],
[4,5,6],
[7,8,9],
[[10,11,12], 13, 14]
];
arr[3]; // equals [[10,11,12], 13, 14]
arr[3][0]; // equals [10,11,12]
arr[3][0][1]; // equals 11
array [0][0]
and even this array [0] [0]
is not allowed. Although JavaScript is able to process this correctly, this may confuse other programmers reading your code.
var ourPets = [+ +```js +var ourPets = [ + { + animalType: "cat", + names: [ + "Meowzer", + "Fluffy", + "Kit-Cat" + ] + }, + { + animalType: "dog", + names: [ + "Spot", + "Bowser", + "Frankie" + ] + } +]; +ourPets[0].names[1]; // "Fluffy" +ourPets[1].names[0]; // "Spot" +``` +
{
animalType: "cat",
names: [
"Meowzer",
"Fluffy",
"Kit-Cat"
]
},
{
animalType: "dog",
names: [
"Spot",
"Bowser",
"Frankie"
]
}
];
ourPets[0].names[1]; // "Fluffy"
ourPets[1].names[0]; // "Spot"
var ourStorage = {+ +```js +var ourStorage = { + "desk": { + "drawer": "stapler" + }, + "cabinet": { + "top drawer": { + "folder1": "a file", + "folder2": "secrets" + }, + "bottom drawer": "soda" + } +}; +ourStorage.cabinet["top drawer"].folder2; // "secrets" +ourStorage.desk.drawer; // "stapler" +``` +
"desk": {
"drawer": "stapler"
},
"cabinet": {
"top drawer": {
"folder1": "a file",
"folder2": "secrets"
},
"bottom drawer": "soda"
}
};
ourStorage.cabinet["top drawer"].folder2; // "secrets"
ourStorage.desk.drawer; // "stapler"
[]
). If the property of the object you are trying to access has a space in its name, you will need to use bracket notation.
However, you can still use bracket notation on object properties without spaces.
Here is a sample of using bracket notation to read an object's property:
-var myObj = {+ +```js +var myObj = { + "Space Name": "Kirk", + "More Space": "Spock", + "NoSpace": "USS Enterprise" +}; +myObj["Space Name"]; // Kirk +myObj['More Space']; // Spock +myObj["NoSpace"]; // USS Enterprise +``` + Note that property names with spaces in them must be in quotes (single or double). diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/accessing-object-properties-with-dot-notation.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/accessing-object-properties-with-dot-notation.english.md index b964787ea2..5eaf0ebc6f 100644 --- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/accessing-object-properties-with-dot-notation.english.md +++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/accessing-object-properties-with-dot-notation.english.md @@ -10,7 +10,16 @@ videoUrl: 'https://scrimba.com/c/cGryJs8' There are two ways to access the properties of an object: dot notation (
"Space Name": "Kirk",
"More Space": "Spock",
"NoSpace": "USS Enterprise"
};
myObj["Space Name"]; // Kirk
myObj['More Space']; // Spock
myObj["NoSpace"]; // USS Enterprise
.
) and bracket notation ([]
), similar to an array.
Dot notation is what you use when you know the name of the property you're trying to access ahead of time.
Here is a sample of using dot notation (.
) to read an object's property:
-var myObj = {+ +```js +var myObj = { + prop1: "val1", + prop2: "val2" +}; +var prop1val = myObj.prop1; // val1 +var prop2val = myObj.prop2; // val2 +``` + ## Instructions diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/accessing-object-properties-with-variables.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/accessing-object-properties-with-variables.english.md index 5f625b8526..8bd792c636 100644 --- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/accessing-object-properties-with-variables.english.md +++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/accessing-object-properties-with-variables.english.md @@ -9,11 +9,30 @@ videoUrl: 'https://scrimba.com/c/cnQyKur'
prop1: "val1",
prop2: "val2"
};
var prop1val = myObj.prop1; // val1
var prop2val = myObj.prop2; // val2
var dogs = {+ +```js +var dogs = { + Fido: "Mutt", Hunter: "Doberman", Snoopie: "Beagle" +}; +var myDog = "Hunter"; +var myBreed = dogs[myDog]; +console.log(myBreed); // "Doberman" +``` + Another way you can use this concept is when the property's name is collected dynamically during the program execution, as follows: -
Fido: "Mutt", - Hunter: "Doberman", - Snoopie: "Beagle"
};
var myDog = "Hunter";
var myBreed = dogs[myDog];
console.log(myBreed); // "Doberman"
var someObj = {+ +```js +var someObj = { + propName: "John" +}; +function propPrefix(str) { + var s = "prop"; + return s + str; +} +var someProp = propPrefix("Name"); // someProp now holds the value 'propName' +console.log(someObj[someProp]); // "John" +``` + Note that we do not use quotes around the variable name when using it to access the property because we are using the value of the variable, not the name.
propName: "John"
};
function propPrefix(str) {
var s = "prop";
return s + str;
}
var someProp = propPrefix("Name"); // someProp now holds the value 'propName'
console.log(someObj[someProp]); // "John"
+
symbol as an addition operator when placed between two numbers.
Example:
-myVar = 5 + 10; // assigned 15+ +```js +myVar = 5 + 10; // assigned 15 +``` + ## Instructions diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/adding-a-default-option-in-switch-statements.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/adding-a-default-option-in-switch-statements.english.md index 971e49d636..60337c0764 100644 --- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/adding-a-default-option-in-switch-statements.english.md +++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/adding-a-default-option-in-switch-statements.english.md @@ -9,7 +9,22 @@ videoUrl: 'https://scrimba.com/c/c3JvVfg'
switch
statement you may not be able to specify all possible values as case
statements. Instead, you can add the default
statement which will be executed if no matching case
statements are found. Think of it like the final else
statement in an if/else
chain.
A default
statement should be the last case.
-switch (num) {+ +```js +switch (num) { + case value1: + statement1; + break; + case value2: + statement2; + break; +... + default: + defaultStatement; + break; +} +``` +
case value1:
statement1;
break;
case value2:
statement2;
break;
...
default:
defaultStatement;
break;
}
object
before.
Objects are similar to arrays
, except that instead of using indexes to access and modify their data, you access the data in objects through what are called properties
.
Objects are useful for storing data in a structured way, and can represent real world objects, like a cat.
Here's a sample cat object:
-var cat = {+ +```js +var cat = { + "name": "Whiskers", + "legs": 4, + "tails": 1, + "enemies": ["Water", "Dogs"] +}; +``` + In this example, all the properties are stored as strings, such as -
"name": "Whiskers",
"legs": 4,
"tails": 1,
"enemies": ["Water", "Dogs"]
};
"name"
, "legs"
, and "tails"
. However, you can also use numbers as properties. You can even omit the quotes for single-word string properties, as follows:
-var anotherObject = {+ +```js +var anotherObject = { + make: "Ford", + 5: "five", + "model": "focus" +}; +``` + However, if your object has any non-string properties, JavaScript will automatically typecast them as strings. diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/chaining-if-else-statements.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/chaining-if-else-statements.english.md index e4b68683d5..185d043048 100644 --- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/chaining-if-else-statements.english.md +++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/chaining-if-else-statements.english.md @@ -8,7 +8,20 @@ videoUrl: 'https://scrimba.com/c/caeJgsw' ## Description
make: "Ford",
5: "five",
"model": "focus"
};
if/else
statements can be chained together for complex logic. Here is pseudocode of multiple chained if
/ else if
statements:
-if (condition1) {+ +```js +if (condition1) { + statement1 +} else if (condition2) { + statement2 +} else if (condition3) { + statement3 +. . . +} else { + statementN +} +``` +
statement1
} else if (condition2) {
statement2
} else if (condition3) {
statement3
. . .
} else {
statementN
}
//
will tell JavaScript to ignore the remainder of the text on the current line:
-// This is an in-line comment.+ +```js +// This is an in-line comment. +``` + You can make a multi-line comment beginning with
/*
and ending with */
:
-/* This is a+ +```js +/* This is a +multi-line comment */ +``` + Best Practice
multi-line comment */
true
or false
value.
The most basic operator is the equality operator ==
. The equality operator compares two values and returns true
if they're equivalent or false
if they are not. Note that equality is different from assignment (=
), which assigns the value at the right of the operator to a variable in the left.
-function equalityTest(myVal) {+ +```js +function equalityTest(myVal) { + if (myVal == 10) { + return "Equal"; + } + return "Not Equal"; +} +``` + If
if (myVal == 10) {
return "Equal";
}
return "Not Equal";
}
myVal
is equal to 10
, the equality operator returns true
, so the code in the curly braces will execute, and the function will return "Equal"
. Otherwise, the function will return "Not Equal"
.
In order for JavaScript to compare two different data types
(for example, numbers
and strings
), it must convert one type to another. This is known as "Type Coercion". Once it does, however, it can compare terms as follows:
-1 == 1 // true+ +```js +1 == 1 // true +1 == 2 // false +1 == '1' // true +"3" == 3 // true +``` +
1 == 2 // false
1 == '1' // true
"3" == 3 // true
>
) compares the values of two numbers. If the number to the left is greater than the number to the right, it returns true
. Otherwise, it returns false
.
Like the equality operator, greater than operator will convert data types of values while comparing.
Examples
-5 > 3 // true+ +```js +5 > 3 // true +7 > '3' // true +2 > 3 // false +'1' > 9 // false +``` + ## Instructions diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-greater-than-or-equal-to-operator.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-greater-than-or-equal-to-operator.english.md index fca695126d..8415457674 100644 --- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-greater-than-or-equal-to-operator.english.md +++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-greater-than-or-equal-to-operator.english.md @@ -10,7 +10,14 @@ videoUrl: 'https://scrimba.com/c/c6KBqtV' The
7 > '3' // true
2 > 3 // false
'1' > 9 // false
greater than or equal to
operator (>=
) compares the values of two numbers. If the number to the left is greater than or equal to the number to the right, it returns true
. Otherwise, it returns false
.
Like the equality operator, greater than or equal to
operator will convert data types while comparing.
Examples
-6 >= 6 // true+ +```js +6 >= 6 // true +7 >= '3' // true +2 >= 3 // false +'7' >= 9 // false +``` + ## Instructions diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-inequality-operator.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-inequality-operator.english.md index ec8daf5b3a..c6bf9b05aa 100644 --- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-inequality-operator.english.md +++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-inequality-operator.english.md @@ -9,7 +9,15 @@ videoUrl: 'https://scrimba.com/c/cdBm9Sr'
7 >= '3' // true
2 >= 3 // false
'7' >= 9 // false
!=
) is the opposite of the equality operator. It means "Not Equal" and returns false
where equality would return true
and vice versa. Like the equality operator, the inequality operator will convert data types of values while comparing.
Examples
-1 != 2 // true+ +```js +1 != 2 // true +1 != "1" // false +1 != '1' // false +1 != true // false +0 != false // false +``` +
1 != "1" // false
1 != '1' // false
1 != true // false
0 != false // false
<
) compares the values of two numbers. If the number to the left is less than the number to the right, it returns true
. Otherwise, it returns false
. Like the equality operator, less than operator converts data types while comparing.
Examples
-2 < 5 // true+ +```js +2 < 5 // true +'3' < 7 // true +5 < 5 // false +3 < 2 // false +'8' < 4 // false +``` +
'3' < 7 // true
5 < 5 // false
3 < 2 // false
'8' < 4 // false
less than or equal to
operator (<=
) compares the values of two numbers. If the number to the left is less than or equal to the number to the right, it returns true
. If the number on the left is greater than the number on the right, it returns false
. Like the equality operator, less than or equal to
converts data types.
Examples
-4 <= 5 // true+ +```js +4 <= 5 // true +'7' <= 7 // true +5 <= 5 // true +3 <= 2 // false +'8' <= 4 // false +``` +
'7' <= 7 // true
5 <= 5 // true
3 <= 2 // false
'8' <= 4 // false
===
) is the counterpart to the equality operator (==
). However, unlike the equality operator, which attempts to convert both values being compared to a common type, the strict equality operator does not perform a type conversion.
If the values being compared have different types, they are considered unequal, and the strict equality operator will return false.
Examples
-3 === 3 // true+ +```js +3 === 3 // true +3 === '3' // false +``` + In the second example,
3 === '3' // false
3
is a Number
type and '3'
is a String
type.
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-strict-inequality-operator.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-strict-inequality-operator.english.md
index 9e559f9bfb..a328f16cd0 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-strict-inequality-operator.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-strict-inequality-operator.english.md
@@ -9,7 +9,13 @@ videoUrl: 'https://scrimba.com/c/cKekkUy'
!==
) is the logical opposite of the strict equality operator. It means "Strictly Not Equal" and returns false
where strict equality would return true
and vice versa. Strict inequality will not convert data types.
Examples
-3 !== 3 // false+ +```js +3 !== 3 // false +3 !== '3' // true +4 !== 3 // true +``` +
3 !== '3' // true
4 !== 3 // true
&&
) returns true
if and only if the operands to the left and right of it are true.
The same effect could be achieved by nesting an if statement inside another if:
-if (num > 5) {+ +```js +if (num > 5) { + if (num < 10) { + return "Yes"; + } +} +return "No"; +``` + will only return "Yes" if
if (num < 10) {
return "Yes";
}
}
return "No";
num
is greater than 5
and less than 10
. The same logic can be written as:
-if (num > 5 && num < 10) {+ +```js +if (num > 5 && num < 10) { + return "Yes"; +} +return "No"; +``` +
return "Yes";
}
return "No";
||
) returns true
if either of the operands is true
. Otherwise, it returns false
.
The logical or operator is composed of two pipe symbols (|
). This can typically be found between your Backspace and Enter keys.
The pattern below should look familiar from prior waypoints:
-if (num > 10) {+ +```js +if (num > 10) { + return "No"; +} +if (num < 5) { + return "No"; +} +return "Yes"; +``` + will return "Yes" only if
return "No";
}
if (num < 5) {
return "No";
}
return "Yes";
num
is between 5
and 10
(5 and 10 included). The same logic can be written as:
-if (num > 10 || num < 5) {+ +```js +if (num > 10 || num < 5) { + return "No"; +} +return "Yes"; +``` + ## Instructions diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/compound-assignment-with-augmented-addition.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/compound-assignment-with-augmented-addition.english.md index 9a66ab63d5..556a108c39 100644 --- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/compound-assignment-with-augmented-addition.english.md +++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/compound-assignment-with-augmented-addition.english.md @@ -11,7 +11,13 @@ In programming, it is common to use assignments to modify the contents of a vari
return "No";
}
return "Yes";
myVar = myVar + 5;
to add 5
to myVar
. Since this is such a common pattern, there are operators which do both a mathematical operation and assignment in one step.
One such operator is the +=
operator.
-var myVar = 1;+ +```js +var myVar = 1; +myVar += 5; +console.log(myVar); // Returns 6 +``` + ## Instructions diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/concatenating-strings-with-plus-operator.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/concatenating-strings-with-plus-operator.english.md index 2043567293..4740b213fc 100644 --- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/concatenating-strings-with-plus-operator.english.md +++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/concatenating-strings-with-plus-operator.english.md @@ -9,7 +9,11 @@ videoUrl: 'https://scrimba.com/c/cNpM8AN'
myVar += 5;
console.log(myVar); // Returns 6
+
operator is used with a String
value, it is called the concatenation operator. You can build a new string out of other strings by concatenating them together.
Example
-'My name is Alan,' + ' I concatenate.'+ +```js +'My name is Alan,' + ' I concatenate.' +``` + Note
initialization
, condition
, and final-expression
.
We'll start at i = 10
and loop while i > 0
. We'll decrement i
by 2 each loop with i -= 2
.
-var ourArray = [];+ +```js +var ourArray = []; +for (var i=10; i > 0; i-=2) { + ourArray.push(i); +} +``` +
for (var i=10; i > 0; i-=2) {
ourArray.push(i);
}
ourArray
will now contain [10,8,6,4,2]
.
Let's change our initialization
and final-expression
so we can count backward by twos by odd numbers.
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/declare-javascript-variables.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/declare-javascript-variables.english.md
index ea167cca89..def2732913 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/declare-javascript-variables.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/declare-javascript-variables.english.md
@@ -12,7 +12,11 @@ For example, computers distinguish between numbers, such as the number 12<
Variables allow computers to store and manipulate data in a dynamic fashion. They do this by using a "label" to point to the data rather than using the data itself. Any of the seven data types may be stored in a variable.
Variables
are similar to the x and y variables you use in mathematics, which means they're a simple name to represent the data we want to refer to. Computer variables
differ from mathematical variables in that they can store different values at different times.
We tell JavaScript to create or declare a variable by putting the keyword var
in front of it, like so:
-var ourName;
+
+```js
+var ourName;
+```
+
creates a variable
called ourName
. In JavaScript we end statements with semicolons.
Variable
names can be made up of numbers, letters, and $
or _
, but may not contain spaces or start with a number.
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/divide-one-number-by-another-with-javascript.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/divide-one-number-by-another-with-javascript.english.md
index fece661520..d158b11299 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/divide-one-number-by-another-with-javascript.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/divide-one-number-by-another-with-javascript.english.md
@@ -11,7 +11,11 @@ We can also divide one number by another.
JavaScript uses the /
symbol for division.
Example
-myVar = 16 / 2; // assigned 8
+
+```js
+myVar = 16 / 2; // assigned 8
+```
+
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/global-vs.-local-scope-in-functions.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/global-vs.-local-scope-in-functions.english.md
index 6de51cab0d..772ca86c42 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/global-vs.-local-scope-in-functions.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/global-vs.-local-scope-in-functions.english.md
@@ -9,7 +9,15 @@ videoUrl: 'https://scrimba.com/c/c2QwKH2'
It is possible to have both local and global variables with the same name. When you do this, the local
variable takes precedence over the global
variable.
In this example:
-var someVar = "Hat";
function myFun() {
var someVar = "Head";
return someVar;
}
+
+```js
+var someVar = "Hat";
+function myFun() {
+ var someVar = "Head";
+ return someVar;
+}
+```
+
The function myFun
will return "Head"
because the local
version of the variable is present.
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/introducing-else-if-statements.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/introducing-else-if-statements.english.md
index 369697734c..6150a5ae7b 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/introducing-else-if-statements.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/introducing-else-if-statements.english.md
@@ -8,7 +8,17 @@ videoUrl: 'https://scrimba.com/c/caeJ2hm'
## Description
If you have multiple conditions that need to be addressed, you can chain if
statements together with else if
statements.
-if (num > 15) {
return "Bigger than 15";
} else if (num < 5) {
return "Smaller than 5";
} else {
return "Between 5 and 15";
}
+
+```js
+if (num > 15) {
+ return "Bigger than 15";
+} else if (num < 5) {
+ return "Smaller than 5";
+} else {
+ return "Between 5 and 15";
+}
+```
+
## Instructions
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/introducing-else-statements.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/introducing-else-statements.english.md
index 1f4c75a3e8..1fcd20e10b 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/introducing-else-statements.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/introducing-else-statements.english.md
@@ -8,7 +8,15 @@ videoUrl: 'https://scrimba.com/c/cek4Efq'
## Description
When a condition for an if
statement is true, the block of code following it is executed. What about when that condition is false? Normally nothing would happen. With an else
statement, an alternate block of code can be executed.
-if (num > 10) {
return "Bigger than 10";
} else {
return "10 or Less";
}
+
+```js
+if (num > 10) {
+ return "Bigger than 10";
+} else {
+ return "10 or Less";
+}
+```
+
## Instructions
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/iterate-odd-numbers-with-a-for-loop.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/iterate-odd-numbers-with-a-for-loop.english.md
index f87a26ddfe..bd55695fef 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/iterate-odd-numbers-with-a-for-loop.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/iterate-odd-numbers-with-a-for-loop.english.md
@@ -9,7 +9,14 @@ videoUrl: 'https://scrimba.com/c/cm8n7T9'
For loops don't have to iterate one at a time. By changing our final-expression
, we can count by even numbers.
We'll start at i = 0
and loop while i < 10
. We'll increment i
by 2 each loop with i += 2
.
-var ourArray = [];
for (var i = 0; i < 10; i += 2) {
ourArray.push(i);
}
+
+```js
+var ourArray = [];
+for (var i = 0; i < 10; i += 2) {
+ ourArray.push(i);
+}
+```
+
ourArray
will now contain [0,2,4,6,8]
.
Let's change our initialization
so we can count by odd numbers.
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/iterate-through-an-array-with-a-for-loop.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/iterate-through-an-array-with-a-for-loop.english.md
index 465d385fcb..9b42cad7c4 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/iterate-through-an-array-with-a-for-loop.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/iterate-through-an-array-with-a-for-loop.english.md
@@ -8,7 +8,14 @@ videoUrl: 'https://scrimba.com/c/caeR3HB'
## Description
A common task in JavaScript is to iterate through the contents of an array. One way to do that is with a for
loop. This code will output each element of the array arr
to the console:
-var arr = [10,9,8,7,6];
for (var i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
+
+```js
+var arr = [10,9,8,7,6];
+for (var i = 0; i < arr.length; i++) {
+ console.log(arr[i]);
+}
+```
+
Remember that Arrays have zero-based numbering, which means the last index of the array is length - 1. Our condition for this loop is i < arr.length
, which stops when i
is at length - 1.
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/iterate-with-javascript-do...while-loops.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/iterate-with-javascript-do...while-loops.english.md
index be7164f8df..ae05eeab89 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/iterate-with-javascript-do...while-loops.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/iterate-with-javascript-do...while-loops.english.md
@@ -8,13 +8,40 @@ videoUrl: 'https://scrimba.com/c/cDqWGcp'
## Description
The next type of loop you will learn is called a do...while
loop. It is called a do...while
loop because it will first do
one pass of the code inside the loop no matter what, and then continue to run the loop while
the specified condition evaluates to true
.
-var ourArray = [];
var i = 0;
do {
ourArray.push(i);
i++;
} while (i < 5);
+
+```js
+var ourArray = [];
+var i = 0;
+do {
+ ourArray.push(i);
+ i++;
+} while (i < 5);
+```
+
The example above behaves similar to other types of loops, and the resulting array will look like [0, 1, 2, 3, 4]
. However, what makes the do...while
different from other loops is how it behaves when the condition fails on the first check. Let's see this in action:
Here is a regular while
loop that will run the code in the loop as long as i < 5
:
-var ourArray = [];
var i = 5;
while (i < 5) {
ourArray.push(i);
i++;
}
+
+```js
+var ourArray = [];
+var i = 5;
+while (i < 5) {
+ ourArray.push(i);
+ i++;
+}
+```
+
In this example, we initialize the value of myArray
to an empty array and the value of i
to 5. When we execute the while
loop, the condition evaluates to false
because i
is not less than 5, so we do not execute the code inside the loop. The result is that ourArray
will end up with no values added to it, and it will still look like []
when all of the code in the example above has completed running.
Now, take a look at a do...while
loop:
-var ourArray = [];
var i = 5;
do {
ourArray.push(i);
i++;
} while (i < 5);
+
+```js
+var ourArray = [];
+var i = 5;
+do {
+ ourArray.push(i);
+ i++;
+} while (i < 5);
+```
+
In this case, we initialize the value of i
to 5, just like we did with the while
loop. When we get to the next line, there is no condition to evaluate, so we go to the code inside the curly braces and execute it. We will add a single element to the array and then increment i
before we get to the condition check. When we finally evaluate the condition i < 5
on the last line, we see that i
is now 6, which fails the conditional check, so we exit the loop and are done. At the end of the above example, the value of ourArray
is [5]
.
Essentially, a do...while
loop ensures that the code inside the loop will run at least once.
Let's try getting a do...while
loop to work by pushing values to an array.
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/iterate-with-javascript-for-loops.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/iterate-with-javascript-for-loops.english.md
index b3c2888c0d..ad65ec5dc8 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/iterate-with-javascript-for-loops.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/iterate-with-javascript-for-loops.english.md
@@ -15,7 +15,14 @@ The initialization
statement is executed one time only before the l
The condition
statement is evaluated at the beginning of every loop iteration and will continue as long as it evaluates to true
. When condition
is false
at the start of the iteration, the loop will stop executing. This means if condition
starts as false
, your loop will never execute.
The final-expression
is executed at the end of each loop iteration, prior to the next condition
check and is usually used to increment or decrement your loop counter.
In the following example we initialize with i = 0
and iterate while our condition i < 5
is true. We'll increment i
by 1
in each loop iteration with i++
as our final-expression
.
-var ourArray = [];
for (var i = 0; i < 5; i++) {
ourArray.push(i);
}
+
+```js
+var ourArray = [];
+for (var i = 0; i < 5; i++) {
+ ourArray.push(i);
+}
+```
+
ourArray
will now contain [0,1,2,3,4]
.
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/iterate-with-javascript-while-loops.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/iterate-with-javascript-while-loops.english.md
index 80b289697d..e285a04776 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/iterate-with-javascript-while-loops.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/iterate-with-javascript-while-loops.english.md
@@ -9,7 +9,16 @@ videoUrl: 'https://scrimba.com/c/c8QbnCM'
You can run the same code multiple times by using a loop.
The first type of loop we will learn is called a while
loop because it runs "while" a specified condition is true and stops once that condition is no longer true.
-var ourArray = [];
var i = 0;
while(i < 5) {
ourArray.push(i);
i++;
}
+
+```js
+var ourArray = [];
+var i = 0;
+while(i < 5) {
+ ourArray.push(i);
+ i++;
+}
+```
+
Let's try getting a while loop to work by pushing values to an array.
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/local-scope-and-functions.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/local-scope-and-functions.english.md
index d6c706a5ed..17f687f7cf 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/local-scope-and-functions.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/local-scope-and-functions.english.md
@@ -9,7 +9,16 @@ videoUrl: 'https://scrimba.com/c/cd62NhM'
Variables which are declared within a function, as well as the function parameters have local scope. That means, they are only visible within that function.
Here is a function myTest
with a local variable called loc
.
-function myTest() {
var loc = "foo";
console.log(loc);
}
myTest(); // logs "foo"
console.log(loc); // loc is not defined
+
+```js
+function myTest() {
+ var loc = "foo";
+ console.log(loc);
+}
+myTest(); // logs "foo"
+console.log(loc); // loc is not defined
+```
+
loc
is not defined outside of the function.
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/logical-order-in-if-else-statements.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/logical-order-in-if-else-statements.english.md
index c264db146b..e03d664c09 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/logical-order-in-if-else-statements.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/logical-order-in-if-else-statements.english.md
@@ -11,11 +11,40 @@ Order is important in if
, else if
statements.
The function is executed from top to bottom so you will want to be careful of what statement comes first.
Take these two functions as an example.
Here's the first:
-function foo(x) {
if (x < 1) {
return "Less than one";
} else if (x < 2) {
return "Less than two";
} else {
return "Greater than or equal to two";
}
}
+
+```js
+function foo(x) {
+ if (x < 1) {
+ return "Less than one";
+ } else if (x < 2) {
+ return "Less than two";
+ } else {
+ return "Greater than or equal to two";
+ }
+}
+```
+
And the second just switches the order of the statements:
-function bar(x) {
if (x < 2) {
return "Less than two";
} else if (x < 1) {
return "Less than one";
} else {
return "Greater than or equal to two";
}
}
+
+```js
+function bar(x) {
+ if (x < 2) {
+ return "Less than two";
+ } else if (x < 1) {
+ return "Less than one";
+ } else {
+ return "Greater than or equal to two";
+ }
+}
+```
+
While these two functions look nearly identical if we pass a number to both we get different outputs.
-foo(0) // "Less than one"
bar(0) // "Less than two"
+
+```js
+foo(0) // "Less than one"
+bar(0) // "Less than two"
+```
+
## Instructions
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/manipulate-arrays-with-pop.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/manipulate-arrays-with-pop.english.md
index 0780a8a740..06d85c5d80 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/manipulate-arrays-with-pop.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/manipulate-arrays-with-pop.english.md
@@ -10,7 +10,14 @@ videoUrl: 'https://scrimba.com/c/cRbVZAB'
Another way to change the data in an array is with the .pop()
function.
.pop()
is used to "pop" a value off of the end of an array. We can store this "popped off" value by assigning it to a variable. In other words, .pop()
removes the last element from an array and returns that element.
Any type of entry can be "popped" off of an array - numbers, strings, even nested arrays.
-var threeArr = [1, 4, 6];
var oneDown = threeArr.pop();
console.log(oneDown); // Returns 6
console.log(threeArr); // Returns [1, 4]
+
+```js
+var threeArr = [1, 4, 6];
+var oneDown = threeArr.pop();
+console.log(oneDown); // Returns 6
+console.log(threeArr); // Returns [1, 4]
+```
+
## Instructions
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/manipulate-arrays-with-push.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/manipulate-arrays-with-push.english.md
index ae349d2c9f..8bb294f1db 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/manipulate-arrays-with-push.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/manipulate-arrays-with-push.english.md
@@ -9,7 +9,13 @@ videoUrl: 'https://scrimba.com/c/cnqmVtJ'
An easy way to append data to the end of an array is via the push()
function.
.push()
takes one or more parameters and "pushes" them onto the end of the array.
-var arr = [1,2,3];
arr.push(4);
// arr is now [1,2,3,4]
+
+```js
+var arr = [1,2,3];
+arr.push(4);
+// arr is now [1,2,3,4]
+```
+
## Instructions
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/manipulating-complex-objects.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/manipulating-complex-objects.english.md
index 52395ebd76..99bf0e53fb 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/manipulating-complex-objects.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/manipulating-complex-objects.english.md
@@ -9,11 +9,41 @@ videoUrl: 'https://scrimba.com/c/c9yNMfR'
Sometimes you may want to store data in a flexible Data Structure. A JavaScript object is one way to handle flexible data. They allow for arbitrary combinations of strings, numbers, booleans, arrays, functions, and objects.
Here's an example of a complex data structure:
-var ourMusic = [
{
"artist": "Daft Punk",
"title": "Homework",
"release_year": 1997,
"formats": [
"CD",
"Cassette",
"LP"
],
"gold": true
}
];
+
+```js
+var ourMusic = [
+ {
+ "artist": "Daft Punk",
+ "title": "Homework",
+ "release_year": 1997,
+ "formats": [
+ "CD",
+ "Cassette",
+ "LP"
+ ],
+ "gold": true
+ }
+];
+```
+
This is an array which contains one object inside. The object has various pieces of metadata about an album. It also has a nested "formats"
array. If you want to add more album records, you can do this by adding records to the top level array.
Objects hold data in a property, which has a key-value format. In the example above, "artist": "Daft Punk"
is a property that has a key of "artist"
and a value of "Daft Punk"
.
JavaScript Object Notation or JSON
is a related data interchange format used to store data.
-{
"artist": "Daft Punk",
"title": "Homework",
"release_year": 1997,
"formats": [
"CD",
"Cassette",
"LP"
],
"gold": true
}
+
+```json
+{
+ "artist": "Daft Punk",
+ "title": "Homework",
+ "release_year": 1997,
+ "formats": [
+ "CD",
+ "Cassette",
+ "LP"
+ ],
+ "gold": true
+}
+```
+
Note
You will need to place a comma after every object in the array, unless it is the last object in the array.
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/modify-array-data-with-indexes.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/modify-array-data-with-indexes.english.md
index 0d688cc5f2..835e53a9ac 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/modify-array-data-with-indexes.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/modify-array-data-with-indexes.english.md
@@ -9,7 +9,12 @@ videoUrl: 'https://scrimba.com/c/czQM4A8'
Unlike strings, the entries of arrays are mutable and can be changed freely.
Example
-var ourArray = [50,40,30];
ourArray[0] = 15; // equals [15,40,30]
+
+```js
+var ourArray = [50,40,30];
+ourArray[0] = 15; // equals [15,40,30]
+```
+
Note
There shouldn't be any spaces between the array name and the square brackets, like array [0]
. Although JavaScript is able to process this correctly, this may confuse other programmers reading your code.
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/multiple-identical-options-in-switch-statements.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/multiple-identical-options-in-switch-statements.english.md
index 6accc1154b..602ec86c2f 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/multiple-identical-options-in-switch-statements.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/multiple-identical-options-in-switch-statements.english.md
@@ -8,7 +8,19 @@ videoUrl: 'https://scrimba.com/c/cdBKWCV'
## Description
If the break
statement is omitted from a switch
statement's case
, the following case
statement(s) are executed until a break
is encountered. If you have multiple inputs with the same output, you can represent them in a switch
statement like this:
-switch(val) {
case 1:
case 2:
case 3:
result = "1, 2, or 3";
break;
case 4:
result = "4 alone";
}
+
+```js
+switch(val) {
+ case 1:
+ case 2:
+ case 3:
+ result = "1, 2, or 3";
+ break;
+ case 4:
+ result = "4 alone";
+}
+```
+
Cases for 1, 2, and 3 will all produce the same result.
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/multiply-two-numbers-with-javascript.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/multiply-two-numbers-with-javascript.english.md
index 9c319d8a90..9d9d253386 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/multiply-two-numbers-with-javascript.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/multiply-two-numbers-with-javascript.english.md
@@ -11,7 +11,11 @@ We can also multiply one number by another.
JavaScript uses the *
symbol for multiplication of two numbers.
Example
-myVar = 13 * 13; // assigned 169
+
+```js
+myVar = 13 * 13; // assigned 169
+```
+
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/nesting-for-loops.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/nesting-for-loops.english.md
index f15671768a..3c6b7a06ee 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/nesting-for-loops.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/nesting-for-loops.english.md
@@ -8,7 +8,18 @@ videoUrl: 'https://scrimba.com/c/cRn6GHM'
## Description
If you have a multi-dimensional array, you can use the same logic as the prior waypoint to loop through both the array and any sub-arrays. Here is an example:
-var arr = [
[1,2], [3,4], [5,6]
];
for (var i=0; i < arr.length; i++) {
for (var j=0; j < arr[i].length; j++) {
console.log(arr[i][j]);
}
}
+
+```js
+var arr = [
+ [1,2], [3,4], [5,6]
+];
+for (var i=0; i < arr.length; i++) {
+ for (var j=0; j < arr[i].length; j++) {
+ console.log(arr[i][j]);
+ }
+}
+```
+
This outputs each sub-element in arr
one at a time. Note that for the inner loop, we are checking the .length
of arr[i]
, since arr[i]
is itself an array.
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/passing-values-to-functions-with-arguments.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/passing-values-to-functions-with-arguments.english.md
index a34d16fa53..0421a4b31a 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/passing-values-to-functions-with-arguments.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/passing-values-to-functions-with-arguments.english.md
@@ -9,7 +9,13 @@ videoUrl: 'https://scrimba.com/c/cy8rahW'
Parameters are variables that act as placeholders for the values that are to be input to a function when it is called. When a function is defined, it is typically defined along with one or more parameters. The actual values that are input (or "passed") into a function when it is called are known as arguments.
Here is a function with two parameters, param1
and param2
:
-function testFun(param1, param2) {
console.log(param1, param2);
}
+
+```js
+function testFun(param1, param2) {
+ console.log(param1, param2);
+}
+```
+
Then we can call testFun
:
testFun("Hello", "World");
We have passed two arguments, "Hello"
and "World"
. Inside the function, param1
will equal "Hello" and param2
will equal "World". Note that you could call testFun
again with different arguments and the parameters would take on the value of the new arguments.
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/practice-comparing-different-values.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/practice-comparing-different-values.english.md
index e4bf078057..cf510b2a93 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/practice-comparing-different-values.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/practice-comparing-different-values.english.md
@@ -10,9 +10,19 @@ videoUrl: 'https://scrimba.com/c/cm8PqCa'
In the last two challenges, we learned about the equality operator (==
) and the strict equality operator (===
). Let's do a quick review and practice using these operators some more.
If the values being compared are not of the same type, the equality operator will perform a type conversion, and then evaluate the values. However, the strict equality operator will compare both the data type and value as-is, without converting one type to the other.
Examples
-3 == '3' // returns true because JavaScript performs type conversion from string to number
3 === '3' // returns false because the types are different and type conversion is not performed
+
+```js
+3 == '3' // returns true because JavaScript performs type conversion from string to number
+3 === '3' // returns false because the types are different and type conversion is not performed
+```
+
Note
In JavaScript, you can determine the type of a variable or a value with the typeof
operator, as follows:
-typeof 3 // returns 'number'
typeof '3' // returns 'string'
+
+```js
+typeof 3 // returns 'number'
+typeof '3' // returns 'string'
+```
+
## Instructions
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/quoting-strings-with-single-quotes.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/quoting-strings-with-single-quotes.english.md
index b405606788..d6fd345601 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/quoting-strings-with-single-quotes.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/quoting-strings-with-single-quotes.english.md
@@ -8,11 +8,25 @@ videoUrl: 'https://scrimba.com/c/cbQmnhM'
## Description
String values in JavaScript may be written with single or double quotes, as long as you start and end with the same type of quote. Unlike some other programming languages, single and double quotes work the same in JavaScript.
-doubleQuoteStr = "This is a string";
singleQuoteStr = 'This is also a string';
+
+```js
+doubleQuoteStr = "This is a string";
+singleQuoteStr = 'This is also a string';
+```
+
The reason why you might want to use one type of quote over the other is if you want to use both in a string. This might happen if you want to save a conversation in a string and have the conversation in quotes. Another use for it would be saving an <a>
tag with various attributes in quotes, all within a string.
-conversation = 'Finn exclaims to Jake, "Algebraic!"';
+
+```js
+conversation = 'Finn exclaims to Jake, "Algebraic!"';
+```
+
However, this becomes a problem if you need to use the outermost quotes within it. Remember, a string has the same kind of quote at the beginning and end. But if you have that same quote somewhere in the middle, the string will stop early and throw an error.
-goodStr = 'Jake asks Finn, "Hey, let\'s go on an adventure?"';
badStr = 'Finn responds, "Let's go!"'; // Throws an error
+
+```js
+goodStr = 'Jake asks Finn, "Hey, let\'s go on an adventure?"';
+badStr = 'Finn responds, "Let's go!"'; // Throws an error
+```
+
In the goodStr above, you can use both quotes safely by using the backslash \
as an escape character.
Note
The backslash \
should not be confused with the forward slash /
. They do not do the same thing.
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/replacing-if-else-chains-with-switch.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/replacing-if-else-chains-with-switch.english.md
index 57b8b74375..27854fd2b3 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/replacing-if-else-chains-with-switch.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/replacing-if-else-chains-with-switch.english.md
@@ -8,9 +8,32 @@ videoUrl: 'https://scrimba.com/c/c3JE8fy'
## Description
If you have many options to choose from, a switch
statement can be easier to write than many chained if
/else if
statements. The following:
-if (val === 1) {
answer = "a";
} else if (val === 2) {
answer = "b";
} else {
answer = "c";
}
+
+```js
+if (val === 1) {
+ answer = "a";
+} else if (val === 2) {
+ answer = "b";
+} else {
+ answer = "c";
+}
+```
+
can be replaced with:
-switch(val) {
case 1:
answer = "a";
break;
case 2:
answer = "b";
break;
default:
answer = "c";
}
+
+```js
+switch(val) {
+ case 1:
+ answer = "a";
+ break;
+ case 2:
+ answer = "b";
+ break;
+ default:
+ answer = "c";
+}
+```
+
## Instructions
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/return-a-value-from-a-function-with-return.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/return-a-value-from-a-function-with-return.english.md
index e06f71c4b1..1605eca9ec 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/return-a-value-from-a-function-with-return.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/return-a-value-from-a-function-with-return.english.md
@@ -9,7 +9,14 @@ videoUrl: 'https://scrimba.com/c/cy87wue'
We can pass values into a function with arguments. You can use a return
statement to send a value back out of a function.
Example
-function plusThree(num) {
return num + 3;
}
var answer = plusThree(5); // 8
+
+```js
+function plusThree(num) {
+ return num + 3;
+}
+var answer = plusThree(5); // 8
+```
+
plusThree
takes an argument for num
and returns a value equal to num + 3
.
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/return-early-pattern-for-functions.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/return-early-pattern-for-functions.english.md
index 4af35bf63b..c2845684db 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/return-early-pattern-for-functions.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/return-early-pattern-for-functions.english.md
@@ -9,7 +9,16 @@ videoUrl: 'https://scrimba.com/c/cQe39Sq'
When a return
statement is reached, the execution of the current function stops and control returns to the calling location.
Example
-function myFun() {
console.log("Hello");
return "World";
console.log("byebye")
}
myFun();
+
+```js
+function myFun() {
+ console.log("Hello");
+ return "World";
+ console.log("byebye")
+}
+myFun();
+```
+
The above outputs "Hello" to the console, returns "World", but "byebye"
is never output, because the function exits at the return
statement.
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/returning-boolean-values-from-functions.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/returning-boolean-values-from-functions.english.md
index 38b9dba648..f78a087fce 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/returning-boolean-values-from-functions.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/returning-boolean-values-from-functions.english.md
@@ -9,9 +9,25 @@ videoUrl: 'https://scrimba.com/c/cp62qAQ'
You may recall from Comparison with the Equality Operator that all comparison operators return a boolean true
or false
value.
Sometimes people use an if/else statement to do a comparison, like this:
-function isEqual(a,b) {
if (a === b) {
return true;
} else {
return false;
}
}
+
+```js
+function isEqual(a,b) {
+ if (a === b) {
+ return true;
+ } else {
+ return false;
+ }
+}
+```
+
But there's a better way to do this. Since ===
returns true
or false
, we can return the result of the comparison:
-function isEqual(a,b) {
return a === b;
}
+
+```js
+function isEqual(a,b) {
+ return a === b;
+}
+```
+
## Instructions
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/selecting-from-many-options-with-switch-statements.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/selecting-from-many-options-with-switch-statements.english.md
index e1da1f8ce4..404ad258b8 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/selecting-from-many-options-with-switch-statements.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/selecting-from-many-options-with-switch-statements.english.md
@@ -9,7 +9,22 @@ videoUrl: 'https://scrimba.com/c/c4mv4fm'
If you have many options to choose from, use a switch
statement. A switch
statement tests a value and can have many case
statements which define various possible values. Statements are executed from the first matched case
value until a break
is encountered.
Here is a pseudocode example:
-switch(num) {
case value1:
statement1;
break;
case value2:
statement2;
break;
...
case valueN:
statementN;
break;
}
+
+```js
+switch(num) {
+ case value1:
+ statement1;
+ break;
+ case value2:
+ statement2;
+ break;
+...
+ case valueN:
+ statementN;
+ break;
+}
+```
+
case
values are tested with strict equality (===
). The break
tells JavaScript to stop executing statements. If the break
is omitted, the next statement will be executed.
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/storing-values-with-the-assignment-operator.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/storing-values-with-the-assignment-operator.english.md
index 21e48e5916..0c9034c540 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/storing-values-with-the-assignment-operator.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/storing-values-with-the-assignment-operator.english.md
@@ -11,7 +11,12 @@ In JavaScript, you can store a value in a variable with the assignmentmyVariable = 5;
This assigns the Number
value 5
to myVariable
.
Assignment always goes from right to left. Everything to the right of the =
operator is resolved before the value is assigned to the variable to the left of the operator.
-myVar = 5;+ +```js +myVar = 5; +myNum = myVar; +``` + This assigns
myNum = myVar;
5
to myVar
and then resolves myVar
to 5
again and assigns it to myNum
.
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/subtract-one-number-from-another-with-javascript.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/subtract-one-number-from-another-with-javascript.english.md
index f1a5991771..a06bbe5eae 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/subtract-one-number-from-another-with-javascript.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/subtract-one-number-from-another-with-javascript.english.md
@@ -11,7 +11,11 @@ We can also subtract one number from another.
JavaScript uses the -
symbol for subtraction.
Example
-myVar = 12 - 6; // assigned 6+ +```js +myVar = 12 - 6; // assigned 6 +``` + diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/testing-objects-for-properties.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/testing-objects-for-properties.english.md index 5250cd2507..898b21509d 100644 --- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/testing-objects-for-properties.english.md +++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/testing-objects-for-properties.english.md @@ -9,7 +9,16 @@ videoUrl: 'https://scrimba.com/c/cm8Q7Ua'
.hasOwnProperty(propname)
method of objects to determine if that object has the given property name. .hasOwnProperty()
returns true
or false
if the property is found or not.
Example
-var myObj = {+ +```js +var myObj = { + top: "hat", + bottom: "pants" +}; +myObj.hasOwnProperty("top"); // true +myObj.hasOwnProperty("middle"); // false +``` +
top: "hat",
bottom: "pants"
};
myObj.hasOwnProperty("top"); // true
myObj.hasOwnProperty("middle"); // false
String
values are immutable, which means that they cannot be altered once created.
For example, the following code:
-var myStr = "Bob";+ +```js +var myStr = "Bob"; +myStr[0] = "J"; +``` + cannot change the value of
myStr[0] = "J";
myStr
to "Job", because the contents of myStr
cannot be altered. Note that this does not mean that myStr
cannot be changed, just that the individual characters of a string literal cannot be changed. The only way to change myStr
would be to assign it with a new string, like this:
-var myStr = "Bob";+ +```js +var myStr = "Bob"; +myStr = "Job"; +``` +
myStr = "Job";
var someVariable;+ +```js +var someVariable; +var anotherVariableName; +var thisVariableNameIsSoLong; +``` + ## Instructions diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/understanding-undefined-value-returned-from-a-function.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/understanding-undefined-value-returned-from-a-function.english.md index 2ec4634ed5..64f75ddb6e 100644 --- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/understanding-undefined-value-returned-from-a-function.english.md +++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/understanding-undefined-value-returned-from-a-function.english.md @@ -9,7 +9,15 @@ videoUrl: 'https://scrimba.com/c/ce2p7cL'
var anotherVariableName;
var thisVariableNameIsSoLong;
return
statement but it does not have to. In the case that the function doesn't have a return
statement, when you call it, the function processes the inner code but the returned value is undefined
.
Example
-var sum = 0;+ +```js +var sum = 0; +function addSum(num) { + sum = sum + num; +} +var returnedValue = addSum(3); // sum will be modified but returned value is undefined +``` +
function addSum(num) {
sum = sum + num;
}
var returnedValue = addSum(3); // sum will be modified but returned value is undefined
addSum
is a function without a return
statement. The function will change the global sum
variable but the returned value of the function is undefined
.
ourDog
:
-var ourDog = {+ +```js +var ourDog = { + "name": "Camper", + "legs": 4, + "tails": 1, + "friends": ["everything!"] +}; +``` + Since he's a particularly happy dog, let's change his name to "Happy Camper". Here's how we update his object's name property:
"name": "Camper",
"legs": 4,
"tails": 1,
"friends": ["everything!"]
};
ourDog.name = "Happy Camper";
or
ourDog["name"] = "Happy Camper";
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/use-conditional-logic-with-if-statements.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/use-conditional-logic-with-if-statements.english.md
index 7d00971f57..f6ad025088 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/use-conditional-logic-with-if-statements.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/use-conditional-logic-with-if-statements.english.md
@@ -12,7 +12,18 @@ When the condition evaluates to true
, the program executes the stat
Pseudocode
if (condition is true) {Example -
statement is executed
}
function test (myCondition) {+ +```js +function test (myCondition) { + if (myCondition) { + return "It was true"; + } + return "It was false"; +} +test(true); // returns "It was true" +test(false); // returns "It was false" +``` + When
if (myCondition) {
return "It was true";
}
return "It was false";
}
test(true); // returns "It was true"
test(false); // returns "It was false"
test
is called with a value of true
, the if
statement evaluates myCondition
to see if it is true
or not. Since it is true
, the function returns "It was true"
. When we call test
with a value of false
, myCondition
is not true
and the statement in the curly braces is not executed and the function returns "It was false"
.
conditional operator
. You can also chain them together to check for multiple conditions.
The following function uses if, else if, and else statements to check multiple conditions:
-function findGreaterOrEqual(a, b) {+ +```js +function findGreaterOrEqual(a, b) { + if (a === b) { + return "a and b are equal"; + } + else if (a > b) { + return "a is greater"; + } + else { + return "b is greater"; + } +} +``` + The above function can be re-written using multiple
if (a === b) {
return "a and b are equal";
}
else if (a > b) {
return "a is greater";
}
else {
return "b is greater";
}
}
conditional operators
:
-function findGreaterOrEqual(a, b) {+ +```js +function findGreaterOrEqual(a, b) { + return (a === b) ? "a and b are equal" : (a > b) ? "a is greater" : "b is greater"; +} +``` +
return (a === b) ? "a and b are equal" : (a > b) ? "a is greater" : "b is greater";
}
condition ? statement-if-true : statement-if-false;
The following function uses an if-else statement to check a condition:
-function findGreater(a, b) {+ +```js +function findGreater(a, b) { + if(a > b) { + return "a is greater"; + } + else { + return "b is greater"; + } +} +``` + This can be re-written using the
if(a > b) {
return "a is greater";
}
else {
return "b is greater";
}
}
conditional operator
:
-function findGreater(a, b) {+ +```js +function findGreater(a, b) { + return a > b ? "a is greater" : "b is greater"; +} +``` + ## Instructions diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/using-objects-for-lookups.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/using-objects-for-lookups.english.md index 6cdb65ff1f..11894b0749 100644 --- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/using-objects-for-lookups.english.md +++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/using-objects-for-lookups.english.md @@ -9,7 +9,25 @@ videoUrl: 'https://scrimba.com/c/cdBk8sM'
return a > b ? "a is greater" : "b is greater";
}
switch
statement or an if/else
chain. This is most useful when you know that your input data is limited to a certain range.
Here is an example of a simple reverse alphabet lookup:
-var alpha = {+ +```js +var alpha = { + 1:"Z", + 2:"Y", + 3:"X", + 4:"W", + ... + 24:"C", + 25:"B", + 26:"A" +}; +alpha[2]; // "Y" +alpha[24]; // "C" + +var value = 2; +alpha[value]; // "Y" +``` +
1:"Z",
2:"Y",
3:"X",
4:"W",
...
24:"C",
25:"B",
26:"A"
};
alpha[2]; // "Y"
alpha[24]; // "C"
var value = 2;
alpha[value]; // "Y"
var sentence = "It was really " + "hot" + ", and we " + "laughed" + " ourselves " + "silly" + ".";+ +```js +var sentence = "It was really " + "hot" + ", and we " + "laughed" + " ourselves " + "silly" + "."; +``` + ## Instructions diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/write-reusable-javascript-with-functions.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/write-reusable-javascript-with-functions.english.md index 2abe8462aa..c83e035070 100644 --- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/write-reusable-javascript-with-functions.english.md +++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/basic-javascript/write-reusable-javascript-with-functions.english.md @@ -9,7 +9,13 @@ videoUrl: 'https://scrimba.com/c/cL6dqfy'
function functionName() {+ +```js +function functionName() { + console.log("Hello World"); +} +``` + You can call or invoke this function by using its name followed by parentheses, like this:
console.log("Hello World");
}
functionName();
Each time the function is called it will print out the message "Hello World"
on the dev console. All of the code between the curly braces will be executed every time the function is called.
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/debugging/catch-missing-open-and-closing-parenthesis-after-a-function-call.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/debugging/catch-missing-open-and-closing-parenthesis-after-a-function-call.english.md
index 999f09824f..9939fbc8f7 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/debugging/catch-missing-open-and-closing-parenthesis-after-a-function-call.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/debugging/catch-missing-open-and-closing-parenthesis-after-a-function-call.english.md
@@ -8,7 +8,15 @@ challengeType: 1
function myFunction() {+ +```js +function myFunction() { + return "You rock!"; +} +let varOne = myFunction; // set to equal a function +let varTwo = myFunction(); // set to equal the string "You rock!" +``` +
return "You rock!";
}
let varOne = myFunction; // set to equal a function
let varTwo = myFunction(); // set to equal the string "You rock!"
'
) and double ("
) quotes to declare a string. Deciding which one to use generally comes down to personal preference, with some exceptions.
Having two choices is great when a string has contractions or another piece of text that's in quotes. Just be careful that you don't close the string too early, which causes a syntax error.
Here are some examples of mixing quotes:
-// These are correct:+ +```js +// These are correct: +const grouchoContraction = "I've had a perfectly wonderful evening, but this wasn't it."; +const quoteInString = "Groucho Marx once said 'Quote me as saying I was mis-quoted.'"; +// This is incorrect: +const uhOhGroucho = 'I've had a perfectly wonderful evening, but this wasn't it.'; +``` + Of course, it is okay to use only one style of quotes. You can escape the quotes inside the string by using the backslash (\) escape character: -
const grouchoContraction = "I've had a perfectly wonderful evening, but this wasn't it.";
const quoteInString = "Groucho Marx once said 'Quote me as saying I was mis-quoted.'";
// This is incorrect:
const uhOhGroucho = 'I've had a perfectly wonderful evening, but this wasn't it.';
// Correct use of same quotes:+ +```js +// Correct use of same quotes: +const allSameQuotes = 'I\'ve had a perfectly wonderful evening, but this wasn\'t it.'; +``` +
const allSameQuotes = 'I\'ve had a perfectly wonderful evening, but this wasn\'t it.';
Off by one errors
(sometimes called OBOE) crop up when you're trying to target a specific index of a string or array (to slice or access a segment), or when looping over the indices of them. JavaScript indexing starts at zero, not one, which means the last index is always one less than the length of the item. If you try to access an index equal to the length, the program may throw an "index out of range" reference error or print undefined
.
When you use string or array methods that take index ranges as arguments, it helps to read the documentation and understand if they are inclusive (the item at the given index is part of what's returned) or not. Here are some examples of off by one errors:
-let alphabet = "abcdefghijklmnopqrstuvwxyz";+ +```js +let alphabet = "abcdefghijklmnopqrstuvwxyz"; +let len = alphabet.length; +for (let i = 0; i <= len; i++) { + // loops one too many times at the end + console.log(alphabet[i]); +} +for (let j = 1; j < len; j++) { + // loops one too few times and misses the first character at index 0 + console.log(alphabet[j]); +} +for (let k = 0; k < len; k++) { + // Goldilocks approves - this is just right + console.log(alphabet[k]); +} +``` +
let len = alphabet.length;
for (let i = 0; i <= len; i++) {
// loops one too many times at the end
console.log(alphabet[i]);
}
for (let j = 1; j < len; j++) {
// loops one too few times and misses the first character at index 0
console.log(alphabet[j]);
}
for (let k = 0; k < len; k++) {
// Goldilocks approves - this is just right
console.log(alphabet[k]);
}
=
, or assignment operator. This leads to unexpected control flow in your program.
As covered in previous challenges, the assignment operator (=
) in JavaScript assigns a value to a variable name. And the ==
and ===
operators check for equality (the triple ===
tests for strict equality, meaning both value and type are the same).
The code below assigns x
to be 2, which evaluates as true
. Almost every value on its own in JavaScript evaluates to true
, except what are known as the "falsy" values: false
, 0
, ""
(an empty string), NaN
, undefined
, and null
.
-let x = 1;+ +```js +let x = 1; +let y = 2; +if (x = y) { + // this code block will run for any value of y (unless y were originally set as a falsy) +} else { + // this code block is what should run (but won't) in this example +} +``` + ## Instructions diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/debugging/prevent-infinite-loops-with-a-valid-terminal-condition.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/debugging/prevent-infinite-loops-with-a-valid-terminal-condition.english.md index 2dbc436d2f..183b24fd39 100644 --- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/debugging/prevent-infinite-loops-with-a-valid-terminal-condition.english.md +++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/debugging/prevent-infinite-loops-with-a-valid-terminal-condition.english.md @@ -8,7 +8,15 @@ challengeType: 1
let y = 2;
if (x = y) {
// this code block will run for any value of y (unless y were originally set as a falsy)
} else {
// this code block is what should run (but won't) in this example
}
while
loop inside loopy()
. Do NOT call this function!
-function loopy() {+ +```js +function loopy() { + while(true) { + console.log("Hello, world!"); + } +} +``` + It's the programmer's job to ensure that the terminal condition, which tells the program when to break out of the loop code, is eventually reached. One error is incrementing or decrementing a counter variable in the wrong direction from the terminal condition. Another one is accidentally resetting a counter or index variable within the loop code, instead of incrementing or decrementing it.
while(true) {
console.log("Hello, world!");
}
}
typeof
to check the data structure, or type, of a variable. This is useful in debugging when working with multiple data types. If you think you're adding two numbers, but one is actually a string, the results can be unexpected. Type errors can lurk in calculations or function calls. Be careful especially when you're accessing and working with external data in the form of a JavaScript Object Notation (JSON) object.
Here are some examples using typeof
:
-console.log(typeof ""); // outputs "string"+ +```js +console.log(typeof ""); // outputs "string" +console.log(typeof 0); // outputs "number" +console.log(typeof []); // outputs "object" +console.log(typeof {}); // outputs "object" +``` + JavaScript recognizes six primitive (immutable) data types:
console.log(typeof 0); // outputs "number"
console.log(typeof []); // outputs "object"
console.log(typeof {}); // outputs "object"
Boolean
, Null
, Undefined
, Number
, String
, and Symbol
(new with ES6) and one type for mutable items: Object
. Note that in JavaScript, arrays are technically a type of object.
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:
-var numArray = [];+ +```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
for (var i = 0; i < 3; i++) {
numArray.push(i);
}
console.log(numArray);
// returns [0, 1, 2]
console.log(i);
// returns 3
var
keyword, i
is declared globally. So when i++
is executed, it updates the global variable. This code is similar to the following:
-var numArray = [];+ +```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
var i;
for (i = 0; i < 3; i++) {
numArray.push(i);
}
console.log(numArray);
// returns [0, 1, 2]
console.log(i);
// returns 3
i
variable. This is because the stored function will always refer to the value of the updated global i
variable.
-var printNumTwo;+ +```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,
for (var i = 0; i < 3; i++) {
if (i === 2) {
printNumTwo = function() {
return i;
};
}
}
console.log(printNumTwo());
// returns 3
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:
-'use strict';+ +```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" +``` +
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.
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/es6/create-an-export-fallback-with-export-default.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/es6/create-an-export-fallback-with-export-default.english.md
index 3851fb2f11..d94e5adab8 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/es6/create-an-export-fallback-with-export-default.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/es6/create-an-export-fallback-with-export-default.english.md
@@ -9,7 +9,13 @@ challengeType: 1
In the export
lesson, you learned about the syntax referred to as a named export. 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 export default. 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 export default
:
-export default function add(x,y) {+ +```js +export default function add(x,y) { + return x + y; +} +``` + Note: Since
return x + y;
}
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
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/es6/create-strings-using-template-literals.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/es6/create-strings-using-template-literals.english.md
index c0a45af601..6defdde90a 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/es6/create-strings-using-template-literals.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/es6/create-strings-using-template-literals.english.md
@@ -9,7 +9,23 @@ challengeType: 1
A new feature of ES6 is the template literal. 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:
-const person = {+ +```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 (
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.
`
), 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.
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/es6/declare-a-read-only-variable-with-the-const-keyword.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/es6/declare-a-read-only-variable-with-the-const-keyword.english.md
index 2ff1077769..fade77a373 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/es6/declare-a-read-only-variable-with-the-const-keyword.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/es6/declare-a-read-only-variable-with-the-const-keyword.english.md
@@ -8,7 +8,13 @@ challengeType: 1
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.
-"use strict";+ +```js +"use strict"; +const FAV_PET = "Cats"; +FAV_PET = "Dogs"; // returns error +``` + As you can see, trying to reassign a variable declared with
const FAV_PET = "Cats";
FAV_PET = "Dogs"; // returns error
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.
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/es6/explore-differences-between-the-var-and-let-keywords.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/es6/explore-differences-between-the-var-and-let-keywords.english.md
index 674f8a8da0..781367209c 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/es6/explore-differences-between-the-var-and-let-keywords.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/es6/explore-differences-between-the-var-and-let-keywords.english.md
@@ -7,17 +7,34 @@ challengeType: 1
## Description
var
keyword is that you can overwrite variable declarations without an error.
-var camper = 'James';+ +```js +var camper = 'James'; +var camper = 'David'; +console.log(camper); +// logs 'David' +``` + As you can see in the code above, the
var camper = 'David';
console.log(camper);
// logs 'David'
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.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.
-let camper = 'James';+ +```js +let camper = 'James'; +let camper = 'David'; // throws an error +``` + This error can be seen in the console of your browser. So unlike
let camper = 'David'; // throws an error
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:
-"use strict";+ +```js +"use strict"; +x = 3.14; // throws an error because x is not declared +``` +
x = 3.14; // throws an error because x is not declared
export default
and its uses. It is important to note that, to import a default export, you need to use a different import
syntax.
In the following example, we have a function, add
, that is the default export of a file, "math_functions"
. Here is how to import it:
-import add from "math_functions";+ +```js +import add from "math_functions"; +add(5,4); // Will return 9 +``` + The syntax differs in one key place - the imported value,
add(5,4); // Will return 9
add
, is not surrounded by curly braces, {}
. Unlike exported values, the primary method of importing a default export is to simply write the value's name after import
.
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.
-"use strict";+ +```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
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]
[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.
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.
-let obj = {+ +```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"} +``` +
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"}
function greeting(name = "Anonymous") {+ +```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
return "Hello " + name;
}
console.log(greeting("John")); // Hello John
console.log(greeting()); // Hello Anonymous
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.
require()
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 import. 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 math_array_functions
has about 20 functions, but I only need one, countItems
, in my current file. The old require()
approach would force me to bring in all 20 functions. With this new import
syntax, I can bring in just the desired function, like so:
-import { countItems } from "math_array_functions"+ +```js +import { countItems } from "math_array_functions" +``` + A description of the above code: -
import { function } from "file_path_goes_here"+ +```js +import { function } from "file_path_goes_here" +// We can also import variables the same way! +``` + There are a few ways to write an
// We can also import variables the same way!
import
statement, but the above is a very common use-case.
Noteimport
statement.
Noteimport
, 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.
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/es6/use--to-import-everything-from-a-file.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/es6/use--to-import-everything-from-a-file.english.md
index 47164c2c9d..7fb8ee7bad 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/es6/use--to-import-everything-from-a-file.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/es6/use--to-import-everything-from-a-file.english.md
@@ -8,9 +8,20 @@ challengeType: 1
import * as
syntax.
Here's an example where the contents of a file named "math_functions"
are imported into a file in the same directory:
-import * as myMathModule from "math_functions";+ +```js +import * as myMathModule from "math_functions"; +myMathModule.add(2,3); +myMathModule.subtract(5,3); +``` + And breaking down that code: -
myMathModule.add(2,3);
myMathModule.subtract(5,3);
import * as object_with_name_of_your_choice from "file_path_goes_here"+ +```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
object_with_name_of_your_choice.imported_function
import * as
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.
const myFunc = function() {+ +```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: -
const myVar = "value";
return myVar;
}
const myFunc = () => {+ +```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
const myVar = "value";
return myVar;
}
return
as well as the brackets surrounding the code. This helps simplify smaller functions into one-line statements:
-const myFunc = () => "value"+ +```js +const myFunc = () => "value" +``` + This code will still return
value
by default.
class
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 new
keyword to instantiate an object.
-var SpaceShuttle = function(targetPlanet){+ +```js +var SpaceShuttle = function(targetPlanet){ + this.targetPlanet = targetPlanet; +} +var zeus = new SpaceShuttle('Jupiter'); +``` + The class syntax simply replaces the constructor function creation: -
this.targetPlanet = targetPlanet;
}
var zeus = new SpaceShuttle('Jupiter');
class SpaceShuttle {+ +```js +class SpaceShuttle { + constructor(targetPlanet) { + this.targetPlanet = targetPlanet; + } +} +const zeus = new SpaceShuttle('Jupiter'); +``` + Notice that the
constructor(targetPlanet) {
this.targetPlanet = targetPlanet;
}
}
const zeus = new SpaceShuttle('Jupiter');
class
keyword declares a new function, and a constructor was added, which would be invoked when new
is called - to create a new object.SpaceShuttle
used above.const [a, b] = [1, 2, 3, 4, 5, 6];+ +```js +const [a, b] = [1, 2, 3, 4, 5, 6]; +console.log(a, b); // 1, 2 +``` + The variable
console.log(a, b); // 1, 2
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:
-const [a, b,,, c] = [1, 2, 3, 4, 5, 6];+ +```js +const [a, b,,, c] = [1, 2, 3, 4, 5, 6]; +console.log(a, b, c); // 1, 2, 5 +``` + ## Instructions diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/es6/use-destructuring-assignment-to-assign-variables-from-nested-objects.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/es6/use-destructuring-assignment-to-assign-variables-from-nested-objects.english.md index e661040c98..13594ed29c 100644 --- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/es6/use-destructuring-assignment-to-assign-variables-from-nested-objects.english.md +++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/es6/use-destructuring-assignment-to-assign-variables-from-nested-objects.english.md @@ -8,7 +8,16 @@ challengeType: 1
console.log(a, b, c); // 1, 2, 5
const a = {+ +```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
start: { x: 5, y: 6 },
end: { x: 6, y: -9 }
};
const { start: { x: startX, y: startY }} = a;
console.log(startX, startY); // 5, 6
startX
is assigned the value of a.start.x
.
var voxel = { x: 3.6, y: 7.4, z: 6.54 };+ +```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: -
var x = voxel.x; // x = 3.6
var y = voxel.y; // y = 7.4
var z = voxel.z; // z = 6.54
const { x, y, z } = voxel; // x = 3.6, y = 7.4, z = 6.54+ +```js +const { x, y, z } = voxel; // x = 3.6, y = 7.4, z = 6.54 +``` + If instead you want to store the values of
voxel.x
into a
, voxel.y
into b
, and voxel.z
into c
, you have that freedom as well.
-const { x: a, y: b, z: c } = voxel; // a = 3.6, b = 7.4, c = 6.54+ +```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
x
and copy the value into a
," and so on.
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/es6/use-destructuring-assignment-to-pass-an-object-as-a-functions-parameters.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/es6/use-destructuring-assignment-to-pass-an-object-as-a-functions-parameters.english.md
index c92b28a8fa..62f1fd4a72 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/es6/use-destructuring-assignment-to-pass-an-object-as-a-functions-parameters.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/es6/use-destructuring-assignment-to-pass-an-object-as-a-functions-parameters.english.md
@@ -8,9 +8,22 @@ challengeType: 1
const profileUpdate = (profileData) => {+ +```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: -
const { name, age, nationality, location } = profileData;
// do something with these variables
}
const profileUpdate = ({ name, age, nationality, location }) => {+ +```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.
/* do something with these fields */
}
Array.prototype.slice()
, as shown below:
-const [a, b, ...arr] = [1, 2, 3, 4, 5, 7];+ +```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
console.log(a, b); // 1, 2
console.log(arr); // [3, 4, 5, 7]
a
and b
take the first and second values from the array. After that, because of rest parameter's presence, arr
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.
import
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 import
, known as export. 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 import
, export
is a non-browser feature.
The following is what we refer to as a named export. With this, we can import any code we export into another file with the import
syntax you learned in the last lesson. Here's an example:
-const capitalizeString = (string) => {+ +```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
return string.charAt(0).toUpperCase() + string.slice(1);
}
export { capitalizeString } // How to export functions.
export const foo = "bar"; // How to export variables.
export
statements into one line, you can take this approach:
-const capitalizeString = (string) => {+ +```js +const capitalizeString = (string) => { + return string.charAt(0).toUpperCase() + string.slice(1); +} +const foo = "bar"; +export { capitalizeString, foo } +``` + Either approach is perfectly acceptable.
return string.charAt(0).toUpperCase() + string.slice(1);
}
const foo = "bar";
export { capitalizeString, foo }
class Book {+ +```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. Note: It is a convention to precede the name of a private variable with an underscore (
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
_
). The practice itself does not make a variable private.
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/es6/use-the-rest-parameter-with-function-parameters.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/es6/use-the-rest-parameter-with-function-parameters.english.md
index 4de3dac6af..63ce547b27 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/es6/use-the-rest-parameter-with-function-parameters.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/es6/use-the-rest-parameter-with-function-parameters.english.md
@@ -8,7 +8,15 @@ challengeType: 1
function howMany(...args) {+ +```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
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.
args
array and allows us to apply map()
, filter()
and reduce()
on the parameters array.
apply()
to compute the maximum value in an array:
-var arr = [6, 89, 3, 45];+ +```js +var arr = [6, 89, 3, 45]; +var maximus = Math.max.apply(null, arr); // returns 89 +``` + We had to use
var maximus = Math.max.apply(null, arr); // returns 89
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.
-const arr = [6, 89, 3, 45];+ +```js +const arr = [6, 89, 3, 45]; +const maximus = Math.max(...arr); // returns 89 +``` +
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:
-const spreaded = ...arr; // will throw a syntax error+ +```js +const spreaded = ...arr; // will throw a syntax error +``` +
// doubles input value and returns it+ +```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. -
const doubler = (item) => item * 2;
// the same function, without the argument parentheses+ +```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. -
const doubler = item => item * 2;
// multiplies the first input value by the second and returns it+ +```js +// multiplies the first input value by the second and returns it +const multiplier = (item, multi) => item * multi; +``` +
const multiplier = (item, multi) => item * multi;
function
as follows:
-const person = {+ +```js +const person = { + name: "Taylor", + sayHello: function() { + return `Hello! My name is ${this.name}.`; + } +}; +``` + With ES6, You can remove the
name: "Taylor",
sayHello: function() {
return `Hello! My name is ${this.name}.`;
}
};
function
keyword and colon altogether when defining functions in objects. Here's an example of this syntax:
-const person = {+ +```js +const person = { + name: "Taylor", + sayHello() { + return `Hello! My name is ${this.name}.`; + } +}; +``` +
name: "Taylor",
sayHello() {
return `Hello! My name is ${this.name}.`;
}
};
const getMousePosition = (x, y) => ({+ +```js +const getMousePosition = (x, y) => ({ + x: x, + y: y +}); +``` +
x: x,
y: y
});
getMousePosition
is a simple function that returns an object containing two fields.
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 tox: x
(or something equivalent) under the hood.
Here is the same function from above rewritten to use this new syntax:
-const getMousePosition = (x, y) => ({ x, y });+ +```js +const getMousePosition = (x, y) => ({ x, y }); +``` +
concat
method as a way to combine arrays into a new one without mutating the original arrays. Compare concat
to the push
method. Push
adds an item to the end of the same array it is called on, which mutates that array. Here's an example:
-var arr = [1, 2, 3];+ +```js +var arr = [1, 2, 3]; +arr.push([4, 5, 6]); +// arr is changed to [1, 2, 3, [4, 5, 6]] +// Not the functional programming way +``` +
arr.push([4, 5, 6]);
// arr is changed to [1, 2, 3, [4, 5, 6]]
// Not the functional programming way
Concat
offers a way to add new items to the end of an array without any mutating side effects.
join
method is used to join the elements of an array together to create a string. It takes an argument for the delimiter that is used to separate the array elements in the string.
Here's an example:
-var arr = ["Hello", "World"];+ +```js +var arr = ["Hello", "World"]; +var str = arr.join(" "); +// Sets str to "Hello World" +``` +
var str = arr.join(" ");
// Sets str to "Hello World"
Concatenation
means to join items end to end. JavaScript offers the concat
method for both strings and arrays that work in the same way. For arrays, the method is called on one, then another array is provided as the argument to concat
, which is added to the end of the first array. It returns a new array and does not mutate either of the original arrays. Here's an example:
-[1, 2, 3].concat([4, 5, 6]);+ +```js +[1, 2, 3].concat([4, 5, 6]); +// Returns a new array [1, 2, 3, 4, 5, 6] +``` +
// Returns a new array [1, 2, 3, 4, 5, 6]
arity
of a function is the number of arguments it requires. Currying
a function means to convert a function of N arity
into N functions of arity
1.
In other words, it restructures a function so it takes one argument, then returns another function that takes the next argument, and so on.
Here's an example:
-//Un-curried function+ +```js +//Un-curried function +function unCurried(x, y) { + return x + y; +} + +//Curried function +function curried(x) { + return function(y) { + return x + y; + } +} +//Alternative using ES6 +const curried = x => y => x + y + +curried(1)(2) // Returns 3 +``` + This is useful in your program if you can't supply all the arguments to a function at one time. You can save each function call into a variable, which will hold the returned function reference that takes the next argument when it's available. Here's an example using the
function unCurried(x, y) {
return x + y;
}
//Curried function
function curried(x) {
return function(y) {
return x + y;
}
} -
//Alternative using ES6 -
const curried = x => y => x + y -
-
curried(1)(2) // Returns 3
curried
function in the example above:
-// Call a curried function in parts:+ +```js +// Call a curried function in parts: +var funcForY = curried(1); +console.log(funcForY(2)); // Prints 3 +``` + Similarly,
var funcForY = curried(1);
console.log(funcForY(2)); // Prints 3
partial application
can be described as applying a few arguments to a function at a time and returning another function that is applied to more arguments.
Here's an example:
-//Impartial function+ +```js +//Impartial function +function impartial(x, y, z) { + return x + y + z; +} +var partialFn = impartial.bind(this, 1, 2); +partialFn(10); // Returns 13 +``` + ## Instructions diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/functional-programming/remove-elements-from-an-array-using-slice-instead-of-splice.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/functional-programming/remove-elements-from-an-array-using-slice-instead-of-splice.english.md index 49c20c9fd3..3f21f393fb 100644 --- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/functional-programming/remove-elements-from-an-array-using-slice-instead-of-splice.english.md +++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/functional-programming/remove-elements-from-an-array-using-slice-instead-of-splice.english.md @@ -7,7 +7,13 @@ challengeType: 1 ## Description
function impartial(x, y, z) {
return x + y + z;
}
var partialFn = impartial.bind(this, 1, 2);
partialFn(10); // Returns 13
splice
method for this, which takes arguments for the index of where to start removing items, then the number of items to remove. If the second argument is not provided, the default is to remove items through the end. However, the splice
method mutates the original array it is called on. Here's an example:
-var cities = ["Chicago", "Delhi", "Islamabad", "London", "Berlin"];+ +```js +var cities = ["Chicago", "Delhi", "Islamabad", "London", "Berlin"]; +cities.splice(3, 1); // Returns "London" and deletes it from the cities array +// cities is now ["Chicago", "Delhi", "Islamabad", "Berlin"] +``` + As we saw in the last challenge, the
cities.splice(3, 1); // Returns "London" and deletes it from the cities array
// cities is now ["Chicago", "Delhi", "Islamabad", "Berlin"]
slice
method does not mutate the original array, but returns a new one which can be saved into a variable. Recall that the slice
method takes two arguments for the indices to begin and end the slice (the end is non-inclusive), and returns those items in a new array. Using the slice
method instead of splice
helps to avoid any array-mutating side effects.
slice
method returns a copy of certain elements of an array. It can take two arguments, the first gives the index of where to begin the slice, the second is the index for where to end the slice (and it's non-inclusive). If the arguments are not provided, the default is to start at the beginning of the array through the end, which is an easy way to make a copy of the entire array. The slice
method does not mutate the original array, but returns a new one.
Here's an example:
-var arr = ["Cat", "Dog", "Tiger", "Zebra"];+ +```js +var arr = ["Cat", "Dog", "Tiger", "Zebra"]; +var newArray = arr.slice(1, 3); +// Sets newArray to ["Dog", "Tiger"] +``` +
var newArray = arr.slice(1, 3);
// Sets newArray to ["Dog", "Tiger"]
sort
method sorts the elements of an array according to the callback function.
For example:
-function ascendingOrder(arr) {+ +```js +function ascendingOrder(arr) { + return arr.sort(function(a, b) { + return a - b; + }); +} +ascendingOrder([1, 5, 2, 3, 4]); +// Returns [1, 2, 3, 4, 5] + +function reverseAlpha(arr) { + return arr.sort(function(a, b) { + return a === b ? 0 : a < b ? 1 : -1; + }); +} +reverseAlpha(['l', 'h', 'z', 'b', 's']); +// Returns ['z', 's', 'l', 'h', 'b'] +``` + JavaScript's default sorting method is by string Unicode point value, which may return unexpected results. Therefore, it is encouraged to provide a callback function to specify how to sort the array items. When such a callback function, normally called
return arr.sort(function(a, b) {
return a - b;
});
}
ascendingOrder([1, 5, 2, 3, 4]);
// Returns [1, 2, 3, 4, 5]
function reverseAlpha(arr) {
return arr.sort(function(a, b) {
return a === b ? 0 : a < b ? 1 : -1;
});
}
reverseAlpha(['l', 'h', 'z', 'b', 's']);
// Returns ['z', 's', 'l', 'h', 'b']
compareFunction
, is supplied, the array elements are sorted according to the return value of the compareFunction
:
If compareFunction(a,b)
returns a value less than 0 for two elements a
and b
, then a
will come before b
.
If compareFunction(a,b)
returns a value greater than 0 for two elements a
and b
, then b
will come before a
.
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/functional-programming/split-a-string-into-an-array-using-the-split-method.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/functional-programming/split-a-string-into-an-array-using-the-split-method.english.md
index 1ff5901de1..32a613e9bb 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/functional-programming/split-a-string-into-an-array-using-the-split-method.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/functional-programming/split-a-string-into-an-array-using-the-split-method.english.md
@@ -8,7 +8,17 @@ challengeType: 1
split
method splits a string into an array of strings. It takes an argument for the delimiter, which can be a character to use to break up the string or a regular expression. For example, if the delimiter is a space, you get an array of words, and if the delimiter is an empty string, you get an array of each character in the string.
Here are two examples that split one string by spaces, then another by digits using a regular expression:
-var str = "Hello World";+ +```js +var str = "Hello World"; +var bySpace = str.split(" "); +// Sets bySpace to ["Hello", "World"] + +var otherString = "How9are7you2today"; +var byDigits = otherString.split(/\d/); +// Sets byDigits to ["How", "are", "you", "today"] +``` + Since strings are immutable, the
var bySpace = str.split(" ");
// Sets bySpace to ["Hello", "World"]
var otherString = "How9are7you2today";
var byDigits = otherString.split(/\d/);
// Sets byDigits to ["How", "are", "you", "today"]
split
method makes it easier to work with them.
every
method works with arrays to check if every element passes a particular test. It returns a Boolean value - true
if all values meet the criteria, false
if not.
For example, the following code would check if every element in the numbers
array is less than 10:
-var numbers = [1, 5, 8, 0, 10, 11];+ +```js +var numbers = [1, 5, 8, 0, 10, 11]; +numbers.every(function(currentValue) { + return currentValue < 10; +}); +// Returns false +``` +
numbers.every(function(currentValue) {
return currentValue < 10;
});
// Returns false
some
method works with arrays to check if any element passes a particular test. It returns a Boolean value - true
if any of the values meet the criteria, false
if not.
For example, the following code would check if any element in the numbers
array is less than 10:
-var numbers = [10, 50, 8, 220, 110, 11];+ +```js +var numbers = [10, 50, 8, 220, 110, 11]; +numbers.some(function(currentValue) { + return currentValue < 10; +}); +// Returns true +``` +
numbers.some(function(currentValue) {
return currentValue < 10;
});
// Returns true
getFirstName() + +```js +getFirstName() getLastName() getFullName() setFirstName(first) setLastName(last) -setFullName(firstAndLast)+setFullName(firstAndLast) +``` + Run the tests to see the expected output for each method. The methods that take an argument must accept only one argument and it has to be a string. These methods must be the only available means of interacting with the object. diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/object-oriented-programming/add-methods-after-inheritance.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/object-oriented-programming/add-methods-after-inheritance.english.md index 52a0a2e816..abe80a0728 100644 --- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/object-oriented-programming/add-methods-after-inheritance.english.md +++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/object-oriented-programming/add-methods-after-inheritance.english.md @@ -8,11 +8,33 @@ challengeType: 1
prototype
object from a supertype
constructor function can still have its own methods in addition to inherited methods.
For example, Bird
is a constructor that inherits its prototype
from Animal
:
-function Animal() { }+ +```js +function Animal() { } +Animal.prototype.eat = function() { + console.log("nom nom nom"); +}; +function Bird() { } +Bird.prototype = Object.create(Animal.prototype); +Bird.prototype.constructor = Bird; +``` + In addition to what is inherited from
Animal.prototype.eat = function() {
console.log("nom nom nom");
};
function Bird() { }
Bird.prototype = Object.create(Animal.prototype);
Bird.prototype.constructor = Bird;
Animal
, you want to add behavior that is unique to Bird
objects. Here, Bird
will get a fly()
function. Functions are added to Bird's
prototype
the same way as any constructor function:
-Bird.prototype.fly = function() {+ +```js +Bird.prototype.fly = function() { + console.log("I'm flying!"); +}; +``` + Now instances of
console.log("I'm flying!");
};
Bird
will have both eat()
and fly()
methods:
-let duck = new Bird();+ +```js +let duck = new Bird(); +duck.eat(); // prints "nom nom nom" +duck.fly(); // prints "I'm flying!" +``` +
duck.eat(); // prints "nom nom nom"
duck.fly(); // prints "I'm flying!"
prototype
individually:
-Bird.prototype.numLegs = 2;+ +```js +Bird.prototype.numLegs = 2; +``` + This becomes tedious after more than a few properties. -
Bird.prototype.eat = function() {+ +```js +Bird.prototype.eat = function() { + console.log("nom nom nom"); +} + +Bird.prototype.describe = function() { + console.log("My name is " + this.name); +} +``` + A more efficient way is to set the
console.log("nom nom nom");
}
Bird.prototype.describe = function() {
console.log("My name is " + this.name);
}
prototype
to a new object that already contains the properties. This way, the properties are added all at once:
-Bird.prototype = {+ +```js +Bird.prototype = { + numLegs: 2, + eat: function() { + console.log("nom nom nom"); + }, + describe: function() { + console.log("My name is " + this.name); + } +}; +``` +
numLegs: 2,
eat: function() {
console.log("nom nom nom");
},
describe: function() {
console.log("My name is " + this.name);
}
};
objects
? A car has wheels. Shops sell items. Birds have wings.
These qualities, or properties
, define what makes up an object
. Note that similar objects
share the same properties
, but may have different values for those properties
. For example, all cars have wheels, but not all cars have the same number of wheels.
Objects
in JavaScript are used to model real-world objects, giving them properties
and behavior just like their real-world counterparts. Here's an example using these concepts to create a duck
object
:
-let duck = {+ +```js +let duck = { + name: "Aflac", + numLegs: 2 +}; +``` + This
name: "Aflac",
numLegs: 2
};
duck
object
has two property/value pairs: a name
of "Aflac" and a numLegs
of 2.
Objects
can have a special type of property
, called a method
.
Methods
are properties
that are functions. This adds different behavior to an object
. Here is the duck
example with a method:
-let duck = {+ +```js +let duck = { + name: "Aflac", + numLegs: 2, + sayName: function() {return "The name of this duck is " + duck.name + ".";} +}; +duck.sayName(); +// Returns "The name of this duck is Aflac." +``` + The example adds the
name: "Aflac",
numLegs: 2,
sayName: function() {return "The name of this duck is " + duck.name + ".";}
};
duck.sayName();
// Returns "The name of this duck is Aflac."
sayName
method
, which is a function that returns a sentence giving the name of the duck
.
Notice that the method
accessed the name
property in the return statement using duck.name
. The next challenge will cover another way to do this.
Constructors
are functions that create new objects. They define properties and behaviors that will belong to the new object. Think of them as a blueprint for the creation of new objects.
Here is an example of a constructor
:
-function Bird() {+ +```js +function Bird() { + this.name = "Albert"; + this.color = "blue"; + this.numLegs = 2; +} +``` + This
this.name = "Albert";
this.color = "blue";
this.numLegs = 2;
}
constructor
defines a Bird
object with properties name
, color
, and numLegs
set to Albert, blue, and 2, respectively.
Constructors
follow a few conventions:
Constructors
are defined with a capitalized name to distinguish them from other functions that are not constructors
.Constructors
use the keyword this
to set properties of the object they will create. Inside the constructor
, this
refers to the new object it will create.Constructors
define properties and behaviors instead of returning a value as other functions might.Bird
and Dog
constructors from last challenge worked well. However, notice that all Birds
that are created with the Bird
constructor are automatically named Albert, are blue in color, and have two legs. What if you want birds with different values for name and color? It's possible to change the properties of each bird manually but that would be a lot of work:
-let swan = new Bird();+ +```js +let swan = new Bird(); +swan.name = "Carlos"; +swan.color = "white"; +``` + Suppose you were writing a program to keep track of hundreds or even thousands of different birds in an aviary. It would take a lot of time to create all the birds, then change the properties to different values for every one. To more easily create different
swan.name = "Carlos";
swan.color = "white";
Bird
objects, you can design your Bird constructor to accept parameters:
-function Bird(name, color) {+ +```js +function Bird(name, color) { + this.name = name; + this.color = color; + this.numLegs = 2; +} +``` + Then pass in the values as arguments to define each unique bird into the
this.name = name;
this.color = color;
this.numLegs = 2;
}
Bird
constructor:
let cardinal = new Bird("Bruce", "red");
This gives a new instance of Bird
with name and color properties set to Bruce and red, respectively. The numLegs
property is still set to 2.
The cardinal
has these properties:
-cardinal.name // => Bruce+ +```js +cardinal.name // => Bruce +cardinal.color // => red +cardinal.numLegs // => 2 +``` + The constructor is more flexible. It's now possible to define the properties for each
cardinal.color // => red
cardinal.numLegs // => 2
Bird
at the time it is created, which is one way that JavaScript constructors are so useful. They group objects together based on shared characteristics and behavior and define a blueprint that automates their creation.
supertype
called Animal
that defined behaviors shared by all animals:
-function Animal() { }+ +```js +function Animal() { } +Animal.prototype.eat = function() { + console.log("nom nom nom"); +}; +``` + This and the next challenge will cover how to reuse
Animal.prototype.eat = function() {
console.log("nom nom nom");
};
Animal's
methods inside Bird
and Dog
without defining them again. It uses a technique called inheritance
.
This challenge covers the first step: make an instance of the supertype
(or parent).
You already know one way to create an instance of Animal
using the new
operator:
-let animal = new Animal();+ +```js +let animal = new Animal(); +``` + There are some disadvantages when using this syntax for
inheritance
, which are too complex for the scope of this challenge. Instead, here's an alternative approach without those disadvantages:
-let animal = Object.create(Animal.prototype);+ +```js +let animal = Object.create(Animal.prototype); +``` +
Object.create(obj)
creates a new object, and sets obj
as the new object's prototype
. Recall that the prototype
is like the "recipe" for creating an object. By setting the prototype
of animal
to be Animal's
prototype
, you are effectively giving the animal
instance the same "recipe" as any other instance of Animal
.
-animal.eat(); // prints "nom nom nom"+ +```js +animal.eat(); // prints "nom nom nom" +animal instanceof Animal; // => true +``` +
animal instanceof Animal; // => true
own
properties and prototype
properties. Own
properties are defined directly on the object instance itself. And prototype
properties are defined on the prototype
.
-function Bird(name) {+ +```js +function Bird(name) { + this.name = name; //own property +} + +Bird.prototype.numLegs = 2; // prototype property + +let duck = new Bird("Donald"); +``` + Here is how you add
this.name = name; //own property
}
Bird.prototype.numLegs = 2; // prototype property
let duck = new Bird("Donald");
duck
's own
properties to the array ownProps
and prototype
properties to the array prototypeProps
:
-let ownProps = [];+ +```js +let ownProps = []; +let prototypeProps = []; + +for (let property in duck) { + if(duck.hasOwnProperty(property)) { + ownProps.push(property); + } else { + prototypeProps.push(property); + } +} + +console.log(ownProps); // prints ["name"] +console.log(prototypeProps); // prints ["numLegs"] +``` +
let prototypeProps = [];
for (let property in duck) {
if(duck.hasOwnProperty(property)) {
ownProps.push(property);
} else {
prototypeProps.push(property);
}
}
console.log(ownProps); // prints ["name"]
console.log(prototypeProps); // prints ["numLegs"]
method
to the duck
obj
sayName: function() {return "The name of this duck is " + duck.name + ".";}
While this is a valid way to access the object's property, there is a pitfall here. If the variable name changes, any code referencing the original name would need to be updated as well. In a short object definition, it isn't a problem, but if an object has many references to its properties there is a greater chance for error.
A way to avoid these issues is with the this
keyword:
-let duck = {+ +```js +let duck = { + name: "Aflac", + numLegs: 2, + sayName: function() {return "The name of this duck is " + this.name + ".";} +}; +``` +
name: "Aflac",
numLegs: 2,
sayName: function() {return "The name of this duck is " + this.name + ".";}
};
this
is a deep topic, and the above example is only one way to use it. In the current context, this
refers to the object that the method is associated with: duck
.
If the object's name is changed to mallard
, it is not necessary to find all the references to duck
in the code. It makes the code reusable and easier to read.
prototype
object:
-ChildObject.prototype = Object.create(ParentObject.prototype);+ +```js +ChildObject.prototype = Object.create(ParentObject.prototype); +``` + Then the
ChildObject
received its own methods by chaining them onto its prototype
:
-ChildObject.prototype.methodName = function() {...};+ +```js +ChildObject.prototype.methodName = function() {...}; +``` + It's possible to override an inherited method. It's done the same way - by adding a method to
ChildObject.prototype
using the same method name as the one to override.
Here's an example of Bird
overriding the eat()
method inherited from Animal
:
-function Animal() { }+ +```js +function Animal() { } +Animal.prototype.eat = function() { + return "nom nom nom"; +}; +function Bird() { } + +// Inherit all methods from Animal +Bird.prototype = Object.create(Animal.prototype); + +// Bird.eat() overrides Animal.eat() +Bird.prototype.eat = function() { + return "peck peck peck"; +}; +``` + If you have an instance
Animal.prototype.eat = function() {
return "nom nom nom";
};
function Bird() { }
// Inherit all methods from Animal
Bird.prototype = Object.create(Animal.prototype);
// Bird.eat() overrides Animal.eat()
Bird.prototype.eat = function() {
return "peck peck peck";
};
let duck = new Bird();
and you call duck.eat()
, this is how JavaScript looks for the method on duck’s
prototype
chain:
1. duck => Is eat() defined here? No.
2. Bird => Is eat() defined here? => Yes. Execute it and stop searching.
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/object-oriented-programming/remember-to-set-the-constructor-property-when-changing-the-prototype.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/object-oriented-programming/remember-to-set-the-constructor-property-when-changing-the-prototype.english.md
index d04a87b73d..1f3e4765ed 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/object-oriented-programming/remember-to-set-the-constructor-property-when-changing-the-prototype.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/object-oriented-programming/remember-to-set-the-constructor-property-when-changing-the-prototype.english.md
@@ -7,9 +7,28 @@ challengeType: 1
## Description
constructor
property! This property can be used to check which constructor function created the instance, but since the property has been overwritten, it now gives false results:
-duck.constructor === Bird; // false -- Oops+ +```js +duck.constructor === Bird; // false -- Oops +duck.constructor === Object; // true, all objects inherit from Object.prototype +duck instanceof Bird; // true, still works +``` + To fix this, whenever a prototype is manually set to a new object, remember to define the
duck.constructor === Object; // true, all objects inherit from Object.prototype
duck instanceof Bird; // true, still works
constructor
property:
-Bird.prototype = {+ +```js +Bird.prototype = { + constructor: Bird, // define the constructor property + numLegs: 2, + eat: function() { + console.log("nom nom nom"); + }, + describe: function() { + console.log("My name is " + this.name); + } +}; +``` +
constructor: Bird, // define the constructor property
numLegs: 2,
eat: function() {
console.log("nom nom nom");
},
describe: function() {
console.log("My name is " + this.name);
}
};
prototype
from another object, it also inherits the supertype
's constructor property.
Here's an example:
-function Bird() { }+ +```js +function Bird() { } +Bird.prototype = Object.create(Animal.prototype); +let duck = new Bird(); +duck.constructor // function Animal(){...} +``` + But
Bird.prototype = Object.create(Animal.prototype);
let duck = new Bird();
duck.constructor // function Animal(){...}
duck
and all instances of Bird
should show that they were constructed by Bird
and not Animal
. To do so, you can manually set Bird's
constructor property to the Bird
object:
-Bird.prototype.constructor = Bird;+ +```js +Bird.prototype.constructor = Bird; +duck.constructor // function Bird(){...} +``` +
duck.constructor // function Bird(){...}
supertype
(or parent) Animal
: making a new instance of Animal
.
This challenge covers the next step: set the prototype
of the subtype
(or child)—in this case, Bird
—to be an instance of Animal
.
-Bird.prototype = Object.create(Animal.prototype);+ +```js +Bird.prototype = Object.create(Animal.prototype); +``` + Remember that the
prototype
is like the "recipe" for creating an object. In a way, the recipe for Bird
now includes all the key "ingredients" from Animal
.
-let duck = new Bird("Donald");+ +```js +let duck = new Bird("Donald"); +duck.eat(); // prints "nom nom nom" +``` +
duck.eat(); // prints "nom nom nom"
duck
inherits all of Animal
's properties, including the eat
method.
Bird
constructor defines two properties: name
and numLegs
:
-function Bird(name) {+ +```js +function Bird(name) { + this.name = name; + this.numLegs = 2; +} + +let duck = new Bird("Donald"); +let canary = new Bird("Tweety"); +``` +
this.name = name;
this.numLegs = 2;
}
let duck = new Bird("Donald");
let canary = new Bird("Tweety");
name
and numLegs
are called own
properties, because they are defined directly on the instance object. That means that duck
and canary
each has its own separate copy of these properties.
In fact every instance of Bird
will have its own copy of these properties.
The following code adds all of the own
properties of duck
to the array ownProps
:
-let ownProps = [];+ +```js +let ownProps = []; + +for (let property in duck) { + if(duck.hasOwnProperty(property)) { + ownProps.push(property); + } +} + +console.log(ownProps); // prints [ "name", "numLegs" ] +``` +
for (let property in duck) {
if(duck.hasOwnProperty(property)) {
ownProps.push(property);
}
}
console.log(ownProps); // prints [ "name", "numLegs" ]
constructor
property located on the object instances duck
and beagle
that were created in the previous challenges:
-let duck = new Bird();+ +```js +let duck = new Bird(); +let beagle = new Dog(); + +console.log(duck.constructor === Bird); //prints true +console.log(beagle.constructor === Dog); //prints true +``` + Note that the
let beagle = new Dog();
console.log(duck.constructor === Bird); //prints true
console.log(beagle.constructor === Dog); //prints true
constructor
property is a reference to the constructor function that created the instance.
The advantage of the constructor
property is that it's possible to check for this property to find out what kind of object it is. Here's an example of how this could be used:
-function joinBirdFraternity(candidate) {+ +```js +function joinBirdFraternity(candidate) { + if (candidate.constructor === Bird) { + return true; + } else { + return false; + } +} +``` + Note
if (candidate.constructor === Bird) {
return true;
} else {
return false;
}
}
constructor
property can be overwritten (which will be covered in the next two challenges) it’s generally better to use the instanceof
method to check the type of an object.
(function () {+ +```js +(function () { + console.log("Chirp, chirp!"); +})(); // this is an anonymous function expression that executes right away +// Outputs "Chirp, chirp!" immediately +``` + Note that the function has no name and is not stored in a variable. The two parentheses () at the end of the function expression cause it to be immediately executed or invoked. This pattern is known as an
console.log("Chirp, chirp!");
})(); // this is an anonymous function expression that executes right away
// Outputs "Chirp, chirp!" immediately
immediately invoked function expression
or IIFE
.
prototype
. Also, an object’s prototype
itself is an object.
-function Bird(name) {+ +```js +function Bird(name) { + this.name = name; +} + +typeof Bird.prototype; // => object +``` + Because a
this.name = name;
}
typeof Bird.prototype; // => object
prototype
is an object, a prototype
can have its own prototype
! In this case, the prototype
of Bird.prototype
is Object.prototype
:
-Object.prototype.isPrototypeOf(Bird.prototype);+ +```js +Object.prototype.isPrototypeOf(Bird.prototype); +// returns true +``` + How is this useful? You may recall the
// returns true
hasOwnProperty
method from a previous challenge:
-let duck = new Bird("Donald");+ +```js +let duck = new Bird("Donald"); +duck.hasOwnProperty("name"); // => true +``` + The
duck.hasOwnProperty("name"); // => true
hasOwnProperty
method is defined in Object.prototype
, which can be accessed by Bird.prototype
, which can then be accessed by duck
. This is an example of the prototype
chain.
In this prototype
chain, Bird
is the supertype
for duck
, while duck
is the subtype
. Object
is a supertype
for both Bird
and duck
.
Object
is a supertype
for all objects in JavaScript. Therefore, any object can use the hasOwnProperty
method.
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/object-oriented-programming/understand-where-an-objects-prototype-comes-from.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/object-oriented-programming/understand-where-an-objects-prototype-comes-from.english.md
index 85ce0fdb4e..494b1f8eea 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/object-oriented-programming/understand-where-an-objects-prototype-comes-from.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/object-oriented-programming/understand-where-an-objects-prototype-comes-from.english.md
@@ -7,9 +7,22 @@ challengeType: 1
## Description
prototype
directly from the constructor function that created it. For example, here the Bird
constructor creates the duck
object:
-function Bird(name) {+ +```js +function Bird(name) { + this.name = name; +} + +let duck = new Bird("Donald"); +``` +
this.name = name;
}
let duck = new Bird("Donald");
duck
inherits its prototype
from the Bird
constructor function. You can show this relationship with the isPrototypeOf
method:
-Bird.prototype.isPrototypeOf(duck);+ +```js +Bird.prototype.isPrototypeOf(duck); +// returns true +``` +
// returns true
Bird
constructor from the previous challenge:
-function Bird() {+ +```js +function Bird() { + this.name = "Albert"; + this.color = "blue"; + this.numLegs = 2; + // "this" inside the constructor always refers to the object being created +} + +let blueBird = new Bird(); +``` + Notice that the
this.name = "Albert";
this.color = "blue";
this.numLegs = 2;
// "this" inside the constructor always refers to the object being created
}
let blueBird = new Bird();
new
operator is used when calling a constructor. This tells JavaScript to create a new instance
of Bird
called blueBird
. Without the new
operator, this
inside the constructor would not point to the newly created object, giving unexpected results.
Now blueBird
has all the properties defined inside the Bird
constructor:
-blueBird.name; // => Albert+ +```js +blueBird.name; // => Albert +blueBird.color; // => blue +blueBird.numLegs; // => 2 +``` + Just like any other object, its properties can be accessed and modified: -
blueBird.color; // => blue
blueBird.numLegs; // => 2
blueBird.name = 'Elvira';+ +```js +blueBird.name = 'Elvira'; +blueBird.name; // => Elvira +``` +
blueBird.name; // => Elvira
Bird
and Airplane
. They can both fly, but a Bird
is not a type of Airplane
and vice versa.
For unrelated objects, it's better to use mixins
. A mixin
allows other objects to use a collection of functions.
-let flyMixin = function(obj) {+ +```js +let flyMixin = function(obj) { + obj.fly = function() { + console.log("Flying, wooosh!"); + } +}; +``` + The
obj.fly = function() {
console.log("Flying, wooosh!");
}
};
flyMixin
takes any object and gives it the fly
method.
-let bird = {+ +```js +let bird = { + name: "Donald", + numLegs: 2 +}; + +let plane = { + model: "777", + numPassengers: 524 +}; + +flyMixin(bird); +flyMixin(plane); +``` + Here
name: "Donald",
numLegs: 2
};
let plane = {
model: "777",
numPassengers: 524
};
flyMixin(bird);
flyMixin(plane);
bird
and plane
are passed into flyMixin
, which then assigns the fly
function to each object. Now bird
and plane
can both fly:
-bird.fly(); // prints "Flying, wooosh!"+ +```js +bird.fly(); // prints "Flying, wooosh!" +plane.fly(); // prints "Flying, wooosh!" +``` + Note how the
plane.fly(); // prints "Flying, wooosh!"
mixin
allows for the same fly
method to be reused by unrelated objects bird
and plane
.
immediately invoked function expression
(IIFE
) is often used to group related functionality into a single object or module
. For example, an earlier challenge defined two mixins:
-function glideMixin(obj) {+ +```js +function glideMixin(obj) { + obj.glide = function() { + console.log("Gliding on the water"); + }; +} +function flyMixin(obj) { + obj.fly = function() { + console.log("Flying, wooosh!"); + }; +} +``` + We can group these
obj.glide = function() {
console.log("Gliding on the water");
};
}
function flyMixin(obj) {
obj.fly = function() {
console.log("Flying, wooosh!");
};
}
mixins
into a module as follows:
-let motionModule = (function () {+ +```js +let motionModule = (function () { + return { + glideMixin: function(obj) { + obj.glide = function() { + console.log("Gliding on the water"); + }; + }, + flyMixin: function(obj) { + obj.fly = function() { + console.log("Flying, wooosh!"); + }; + } + } +})(); // The two parentheses cause the function to be immediately invoked +``` + Note that you have an
return {
glideMixin: function(obj) {
obj.glide = function() {
console.log("Gliding on the water");
};
},
flyMixin: function(obj) {
obj.fly = function() {
console.log("Flying, wooosh!");
};
}
}
})(); // The two parentheses cause the function to be immediately invoked
immediately invoked function expression
(IIFE
) that returns an object motionModule
. This returned object contains all of the mixin
behaviors as properties of the object.
The advantage of the module
pattern is that all of the motion behaviors can be packaged into a single object that can then be used by other parts of your code. Here is an example using it:
-motionModule.glideMixin(duck);+ +```js +motionModule.glideMixin(duck); +duck.glide(); +``` +
duck.glide();
bird
had a public property name
. It is considered public because it can be accessed and changed outside of bird
's definition.
-bird.name = "Duffy";+ +```js +bird.name = "Duffy"; +``` + Therefore, any part of your code can easily change the name of
bird
to any value. Think about things like passwords and bank accounts being easily changeable by any part of your codebase. That could cause a lot of issues.
The simplest way to make this public property private is by creating a variable within the constructor function. This changes the scope of that variable to be within the constructor function versus available globally. This way, the variable can only be accessed and changed by methods also within the constructor function.
-function Bird() {+ +```js +function Bird() { + let hatchedEgg = 10; // private variable + + /* publicly available method that a bird object can use */ + this.getHatchedEggCount = function() { + return hatchedEgg; + }; +} +let ducky = new Bird(); +ducky.getHatchedEggCount(); // returns 10 +``` + Here
let hatchedEgg = 10; // private variable
/* publicly available method that a bird object can use */
this.getHatchedEggCount = function() {
return hatchedEgg;
};
}
let ducky = new Bird();
ducky.getHatchedEggCount(); // returns 10
getHachedEggCount
is a privileged method, because it has access to the private variable hatchedEgg
. This is possible because hatchedEgg
is declared in the same context as getHachedEggCount
. In JavaScript, a function always has access to the context in which it was created. This is called closure
.
object
with various properties
, now you'll see how to access the values of those properties
. Here's an example:
-let duck = {+ +```js +let duck = { + name: "Aflac", + numLegs: 2 +}; +console.log(duck.name); +// This prints "Aflac" to the console +``` + Dot notation is used on the
name: "Aflac",
numLegs: 2
};
console.log(duck.name);
// This prints "Aflac" to the console
object
name, duck
, followed by the name of the property
, name
, to access the value of "Aflac".
Don't Repeat Yourself (DRY)
. The reason repeated code is a problem is because any change requires fixing code in multiple places. This usually means more work for programmers and more room for errors.
Notice in the example below that the describe
method is shared by Bird
and Dog
:
-Bird.prototype = {+ +```js +Bird.prototype = { + constructor: Bird, + describe: function() { + console.log("My name is " + this.name); + } +}; + +Dog.prototype = { + constructor: Dog, + describe: function() { + console.log("My name is " + this.name); + } +}; +``` + The
constructor: Bird,
describe: function() {
console.log("My name is " + this.name);
}
};
Dog.prototype = {
constructor: Dog,
describe: function() {
console.log("My name is " + this.name);
}
};
describe
method is repeated in two places. The code can be edited to follow the DRY
principle by creating a supertype
(or parent) called Animal
:
-function Animal() { };+ +```js +function Animal() { }; + +Animal.prototype = { + constructor: Animal, + describe: function() { + console.log("My name is " + this.name); + } +}; +``` + Since
Animal.prototype = {
constructor: Animal,
describe: function() {
console.log("My name is " + this.name);
}
};
Animal
includes the describe
method, you can remove it from Bird
and Dog
:
-Bird.prototype = {+ +```js +Bird.prototype = { + constructor: Bird +}; + +Dog.prototype = { + constructor: Dog +}; +``` +
constructor: Bird
};
Dog.prototype = {
constructor: Dog
};
numLegs
will probably have the same value for all instances of Bird
, you essentially have a duplicated variable numLegs
inside each Bird
instance.
This may not be an issue when there are only two instances, but imagine if there are millions of instances. That would be a lot of duplicated variables.
A better way is to use Bird’s
prototype
. The prototype
is an object that is shared among ALL instances of Bird
. Here's how to add numLegs
to the Bird prototype
:
-Bird.prototype.numLegs = 2;+ +```js +Bird.prototype.numLegs = 2; +``` + Now all instances of
Bird
have the numLegs
property.
-console.log(duck.numLegs); // prints 2+ +```js +console.log(duck.numLegs); // prints 2 +console.log(canary.numLegs); // prints 2 +``` + Since all instances automatically have the properties on the
console.log(canary.numLegs); // prints 2
prototype
, think of a prototype
as a "recipe" for creating objects.
Note that the prototype
for duck
and canary
is part of the Bird
constructor as Bird.prototype
. Nearly every object in JavaScript has a prototype
property which is part of the constructor function that created it.
instance
of its constructor. JavaScript gives a convenient way to verify this with the instanceof
operator. instanceof
allows you to compare an object to a constructor, returning true
or false
based on whether or not that object was created with the constructor. Here's an example:
-let Bird = function(name, color) {+ +```js +let Bird = function(name, color) { + this.name = name; + this.color = color; + this.numLegs = 2; +} + +let crow = new Bird("Alexis", "black"); + +crow instanceof Bird; // => true +``` + If an object is created without using a constructor,
this.name = name;
this.color = color;
this.numLegs = 2;
}
let crow = new Bird("Alexis", "black");
crow instanceof Bird; // => true
instanceof
will verify that it is not an instance of that constructor:
-let canary = {+ +```js +let canary = { + name: "Mildred", + color: "Yellow", + numLegs: 2 +}; + +canary instanceof Bird; // => false +``` +
name: "Mildred",
color: "Yellow",
numLegs: 2
};
canary instanceof Bird; // => false
?
. This checks for zero or one of the preceding element. You can think of this symbol as saying the previous element is optional.
For example, there are slight differences in American and British English and you can use the question mark to match both spellings.
-let american = "color";+ +```js +let american = "color"; +let british = "colour"; +let rainbowRegex= /colou?r/; +rainbowRegex.test(american); // Returns true +rainbowRegex.test(british); // Returns true +``` +
let british = "colour";
let rainbowRegex= /colou?r/;
rainbowRegex.test(american); // Returns true
rainbowRegex.test(british); // Returns true
()
.
If you want to find either Penguin
or Pumpkin
in a string, you can use the following Regular Expression: /P(engu|umpk)in/g
Then check whether the desired string groups are in the test string by using the test()
method.
-let testStr = "Pumpkin";+ +```js +let testStr = "Pumpkin"; +let testRegex = /P(engu|umpk)in/g; +testRegex.test(testStr); +// Returns true +``` + ## Instructions diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/extract-matches.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/extract-matches.english.md index e903be3464..d040f2723a 100644 --- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/extract-matches.english.md +++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/extract-matches.english.md @@ -8,7 +8,16 @@ challengeType: 1
let testRegex = /P(engu|umpk)in/g;
testRegex.test(testStr);
// Returns true
.match()
method.
To use the .match()
method, apply the method on a string and pass in the regex inside the parentheses. Here's an example:
-"Hello, World!".match(/Hello/);+ +```js +"Hello, World!".match(/Hello/); +// Returns ["Hello"] +let ourStr = "Regular expressions"; +let ourRegex = /expressions/; +ourStr.match(ourRegex); +// Returns ["expressions"] +``` +
// Returns ["Hello"]
let ourStr = "Regular expressions";
let ourRegex = /expressions/;
ourStr.match(ourRegex);
// Returns ["expressions"]
let testStr = "Repeat, Repeat, Repeat";+ +```js +let testStr = "Repeat, Repeat, Repeat"; +let ourRegex = /Repeat/; +testStr.match(ourRegex); +// Returns ["Repeat"] +``` + To search or extract a pattern more than once, you can use the
let ourRegex = /Repeat/;
testStr.match(ourRegex);
// Returns ["Repeat"]
g
flag.
-let repeatRegex = /Repeat/g;+ +```js +let repeatRegex = /Repeat/g; +testStr.match(repeatRegex); +// Returns ["Repeat", "Repeat", "Repeat"] +``` +
testStr.match(repeatRegex);
// Returns ["Repeat", "Repeat", "Repeat"]
/z+/
matches the letter z
when it appears one or more times in a row. It would find matches in all of the following strings:
-"z"+ +```js +"z" +"zzzzzz" +"ABCzzzz" +"zzzzABC" +"abczzzzzzzzzzzzzzzzzzzzzabc" +``` + But it does not find matches in the following strings since there are no letter
"zzzzzz"
"ABCzzzz"
"zzzzABC"
"abczzzzzzzzzzzzzzzzzzzzzabc"
z
characters:
-""+ +```js +"" +"ABC" +"abcabc" +``` + ## Instructions diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/match-all-letters-and-numbers.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/match-all-letters-and-numbers.english.md index c29964d274..a60d0d30b0 100644 --- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/match-all-letters-and-numbers.english.md +++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/match-all-letters-and-numbers.english.md @@ -8,7 +8,18 @@ challengeType: 1
"ABC"
"abcabc"
[a-z]
. This kind of character class is common enough that there is a shortcut for it, although it includes a few extra characters as well.
The closest character class in JavaScript to match the alphabet is \w
. This shortcut is equal to [A-Za-z0-9_]
. This character class matches upper and lowercase letters plus numbers. Note, this character class also includes the underscore character (_
).
-let longHand = /[A-Za-z0-9_]+/;+ +```js +let longHand = /[A-Za-z0-9_]+/; +let shortHand = /\w+/; +let numbers = "42"; +let varNames = "important_var"; +longHand.test(numbers); // Returns true +shortHand.test(numbers); // Returns true +longHand.test(varNames); // Returns true +shortHand.test(varNames); // Returns true +``` + These shortcut character classes are also known as
let shortHand = /\w+/;
let numbers = "42";
let varNames = "important_var";
longHand.test(numbers); // Returns true
shortHand.test(numbers); // Returns true
longHand.test(varNames); // Returns true
shortHand.test(varNames); // Returns true
shorthand character classes
.
.
The wildcard character .
will match any one character. The wildcard is also called dot
and period
. You can use the wildcard character just like any other character in the regex. For example, if you wanted to match "hug"
, "huh"
, "hut"
, and "hum"
, you can use the regex /hu./
to match all four words.
-let humStr = "I'll hum a song";+ +```js +let humStr = "I'll hum a song"; +let hugStr = "Bear hug"; +let huRegex = /hu./; +humStr.test(huRegex); // Returns true +hugStr.test(huRegex); // Returns true +``` +
let hugStr = "Bear hug";
let huRegex = /hu./;
humStr.test(huRegex); // Returns true
hugStr.test(huRegex); // Returns true
caret
character (^
) inside a character set
to create a negated character set
in the form [^thingsThatWillNotBeMatched]
. Outside of a character set
, the caret
is used to search for patterns at the beginning of strings.
-let firstString = "Ricky is first and can be found.";+ +```js +let firstString = "Ricky is first and can be found."; +let firstRegex = /^Ricky/; +firstRegex.test(firstString); +// Returns true +let notFirst = "You can't find Ricky now."; +firstRegex.test(notFirst); +// Returns false +``` +
let firstRegex = /^Ricky/;
firstRegex.test(firstString);
// Returns true
let notFirst = "You can't find Ricky now.";
firstRegex.test(notFirst);
// Returns false
+
sign to look for characters that occur one or more times. There's also an option that matches characters that occur zero or more times.
The character to do this is the asterisk
or star
: *
.
-let soccerWord = "gooooooooal!";+ +```js +let soccerWord = "gooooooooal!"; +let gPhrase = "gut feeling"; +let oPhrase = "over the moon"; +let goRegex = /go*/; +soccerWord.match(goRegex); // Returns ["goooooooo"] +gPhrase.match(goRegex); // Returns ["g"] +oPhrase.match(goRegex); // Returns null +``` +
let gPhrase = "gut feeling";
let oPhrase = "over the moon";
let goRegex = /go*/;
soccerWord.match(goRegex); // Returns ["goooooooo"]
gPhrase.match(goRegex); // Returns ["g"]
oPhrase.match(goRegex); // Returns null
caret
character to search for patterns at the beginning of strings. There is also a way to search for patterns at the end of strings.
You can search the end of strings using the dollar sign
character $
at the end of the regex.
-let theEnding = "This is a never ending story";+ +```js +let theEnding = "This is a never ending story"; +let storyRegex = /story$/; +storyRegex.test(theEnding); +// Returns true +let noEnding = "Sometimes a story will have to end"; +storyRegex.test(noEnding); +// Returns false + +``` +
let storyRegex = /story$/;
storyRegex.test(theEnding);
// Returns true
let noEnding = "Sometimes a story will have to end";
storyRegex.test(noEnding);
// Returns false
[A-Za-z0-9_]
using \w
. A natural pattern you might want to search for is the opposite of alphanumerics.
You can search for the opposite of the \w
with \W
. Note, the opposite pattern uses a capital letter. This shortcut is the same as [^A-Za-z0-9_]
.
-let shortHand = /\W/;+ +```js +let shortHand = /\W/; +let numbers = "42%"; +let sentence = "Coding!"; +numbers.match(shortHand); // Returns ["%"] +sentence.match(shortHand); // Returns ["!"] +``` +
let numbers = "42%";
let sentence = "Coding!";
numbers.match(shortHand); // Returns ["%"]
sentence.match(shortHand); // Returns ["!"]
character sets
to specify a group of characters to match, but that's a lot of typing when you need to match a large range of characters (for example, every letter in the alphabet). Fortunately, there is a built-in feature that makes this short and simple.
Inside a character set
, you can define a range of characters to match using a hyphen
character: -
.
For example, to match lowercase letters a
through e
you would use [a-e]
.
-let catStr = "cat";+ +```js +let catStr = "cat"; +let batStr = "bat"; +let matStr = "mat"; +let bgRegex = /[a-e]at/; +catStr.match(bgRegex); // Returns ["cat"] +batStr.match(bgRegex); // Returns ["bat"] +matStr.match(bgRegex); // Returns null +``` + ## Instructions diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/match-literal-strings.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/match-literal-strings.english.md index 2135001bb8..10b7240529 100644 --- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/match-literal-strings.english.md +++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/match-literal-strings.english.md @@ -7,9 +7,22 @@ challengeType: 1 ## Description
let batStr = "bat";
let matStr = "mat";
let bgRegex = /[a-e]at/;
catStr.match(bgRegex); // Returns ["cat"]
batStr.match(bgRegex); // Returns ["bat"]
matStr.match(bgRegex); // Returns null
"Hello"
using the regular expression /Hello/
. That regex searched for a literal match of the string "Hello"
. Here's another example searching for a literal match of the string "Kevin"
:
-let testStr = "Hello, my name is Kevin.";+ +```js +let testStr = "Hello, my name is Kevin."; +let testRegex = /Kevin/; +testRegex.test(testStr); +// Returns true +``` + Any other forms of
let testRegex = /Kevin/;
testRegex.test(testStr);
// Returns true
"Kevin"
will not match. For example, the regex /Kevin/
will not match "kevin"
or "KEVIN"
.
-let wrongRegex = /kevin/;+ +```js +let wrongRegex = /kevin/; +wrongRegex.test(testStr); +// Returns false +``` + A future challenge will show how to match those other forms as well.
wrongRegex.test(testStr);
// Returns false
\s
, with a lowercase s
. You can also search for everything except whitespace.
Search for non-whitespace using \S
, which is an uppercase s
. This pattern will not match whitespace, carriage return, tab, form feed, and new line characters. You can think of it being similar to the character class [^ \r\t\f\n\v]
.
-let whiteSpace = "Whitespace. Whitespace everywhere!"+ +```js +let whiteSpace = "Whitespace. Whitespace everywhere!" +let nonSpaceRegex = /\S/g; +whiteSpace.match(nonSpaceRegex).length; // Returns 32 +``` +
let nonSpaceRegex = /\S/g;
whiteSpace.match(nonSpaceRegex).length; // Returns 32
-
) to match a range of characters is not limited to letters. It also works to match a range of numbers.
For example, /[0-5]/
matches any number between 0
and 5
, including the 0
and 5
.
Also, it is possible to combine a range of letters and numbers in a single character set.
-let jennyStr = "Jenny8675309";+ +```js +let jennyStr = "Jenny8675309"; +let myRegex = /[a-z0-9]/ig; +// matches all letters and numbers in jennyStr +jennyStr.match(myRegex); +``` + ## Instructions diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/match-single-character-with-multiple-possibilities.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/match-single-character-with-multiple-possibilities.english.md index 589060efb2..86db3d76cc 100644 --- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/match-single-character-with-multiple-possibilities.english.md +++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/match-single-character-with-multiple-possibilities.english.md @@ -9,7 +9,19 @@ challengeType: 1 You learned how to match literal patterns (
let myRegex = /[a-z0-9]/ig;
// matches all letters and numbers in jennyStr
jennyStr.match(myRegex);
/literal/
) and wildcard character (/./
). Those are the extremes of regular expressions, where one finds exact matches and the other matches everything. There are options that are a balance between the two extremes.
You can search for a literal pattern with some flexibility with character classes
. Character classes allow you to define a group of characters you wish to match by placing them inside square ([
and ]
) brackets.
For example, you want to match "bag"
, "big"
, and "bug"
but not "bog"
. You can create the regex /b[aiu]g/
to do this. The [aiu]
is the character class that will only match the characters "a"
, "i"
, or "u"
.
-let bigStr = "big";+ +```js +let bigStr = "big"; +let bagStr = "bag"; +let bugStr = "bug"; +let bogStr = "bog"; +let bgRegex = /b[aiu]g/; +bigStr.match(bgRegex); // Returns ["big"] +bagStr.match(bgRegex); // Returns ["bag"] +bugStr.match(bgRegex); // Returns ["bug"] +bogStr.match(bgRegex); // Returns null +``` + ## Instructions diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/match-whitespace.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/match-whitespace.english.md index a6bc5cfd08..4214d21ca6 100644 --- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/match-whitespace.english.md +++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/match-whitespace.english.md @@ -8,7 +8,14 @@ challengeType: 1
let bagStr = "bag";
let bugStr = "bug";
let bogStr = "bog";
let bgRegex = /b[aiu]g/;
bigStr.match(bgRegex); // Returns ["big"]
bagStr.match(bgRegex); // Returns ["bag"]
bugStr.match(bgRegex); // Returns ["bug"]
bogStr.match(bgRegex); // Returns null
\s
, which is a lowercase s
. This pattern not only matches whitespace, but also carriage return, tab, form feed, and new line characters. You can think of it as similar to the character class [ \r\t\f\n\v]
.
-let whiteSpace = "Whitespace. Whitespace everywhere!"+ +```js +let whiteSpace = "Whitespace. Whitespace everywhere!" +let spaceRegex = /\s/g; +whiteSpace.match(spaceRegex); +// Returns [" ", " "] +``` +
let spaceRegex = /\s/g;
whiteSpace.match(spaceRegex);
// Returns [" ", " "]
lookaheads
: positive lookahead
A positive lookahead
will look to make sure the element in the search pattern is there, but won't actually match it. A positive lookahead is used as (?=...)
where the ...
is the required part that is not matched.
On the other hand, a negative lookahead
will look to make sure the element in the search pattern is not there. A negative lookahead is used as (?!...)
where the ...
is the pattern that you do not want to be there. The rest of the pattern is returned if the negative lookahead part is not present.
Lookaheads are a bit confusing but some examples will help.
-let quit = "qu";+ +```js +let quit = "qu"; +let noquit = "qt"; +let quRegex= /q(?=u)/; +let qRegex = /q(?!u)/; +quit.match(quRegex); // Returns ["q"] +noquit.match(qRegex); // Returns ["q"] +``` + A more practical use of
let noquit = "qt";
let quRegex= /q(?=u)/;
let qRegex = /q(?!u)/;
quit.match(quRegex); // Returns ["q"]
noquit.match(qRegex); // Returns ["q"]
lookaheads
is to check two or more patterns in one string. Here is a (naively) simple password checker that looks for between 3 and 6 characters and at least one number:
-let password = "abc123";+ +```js +let password = "abc123"; +let checkPass = /(?=\w{3,6})(?=\D*\d)/; +checkPass.test(password); // Returns true +``` + ## Instructions diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/reuse-patterns-using-capture-groups.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/reuse-patterns-using-capture-groups.english.md index 121f58c8c5..ea164fec30 100644 --- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/reuse-patterns-using-capture-groups.english.md +++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/reuse-patterns-using-capture-groups.english.md @@ -10,7 +10,14 @@ Some patterns you search for will occur multiple times in a string. It is wastef You can search for repeat substrings using
let checkPass = /(?=\w{3,6})(?=\D*\d)/;
checkPass.test(password); // Returns true
capture groups
. Parentheses, (
and )
, are used to find repeat substrings. You put the regex of the pattern that will repeat in between the parentheses.
To specify where that repeat string will appear, you use a backslash (\
) and then a number. This number starts at 1 and increases with each additional capture group you use. An example would be \1
to match the first group.
The example below matches any word that occurs twice separated by a space:
-let repeatStr = "regex regex";+ +```js +let repeatStr = "regex regex"; +let repeatRegex = /(\w+)\s\1/; +repeatRegex.test(repeatStr); // Returns true +repeatStr.match(repeatRegex); // Returns ["regex regex", "regex"] +``` + Using the
let repeatRegex = /(\w+)\s\1/;
repeatRegex.test(repeatStr); // Returns true
repeatStr.match(repeatRegex); // Returns ["regex regex", "regex"]
.match()
method on a string will return an array with the string it matches, along with its capture group.
diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/specify-exact-number-of-matches.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/specify-exact-number-of-matches.english.md
index cc0bdb13d7..f9546fa494 100644
--- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/specify-exact-number-of-matches.english.md
+++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/specify-exact-number-of-matches.english.md
@@ -9,7 +9,17 @@ challengeType: 1
You can specify the lower and upper number of patterns with quantity specifiers
using curly brackets. Sometimes you only want a specific number of matches.
To specify a certain number of patterns, just have that one number between the curly brackets.
For example, to match only the word "hah"
with the letter a
3
times, your regex would be /ha{3}h/
.
-let A4 = "haaaah";+ +```js +let A4 = "haaaah"; +let A3 = "haaah"; +let A100 = "h" + "a".repeat(100) + "h"; +let multipleHA = /ha{3}h/; +multipleHA.test(A4); // Returns false +multipleHA.test(A3); // Returns true +multipleHA.test(A100); // Returns false +``` + ## Instructions diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/specify-only-the-lower-number-of-matches.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/specify-only-the-lower-number-of-matches.english.md index 051833cfb0..93a63d0e26 100644 --- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/specify-only-the-lower-number-of-matches.english.md +++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/specify-only-the-lower-number-of-matches.english.md @@ -9,7 +9,17 @@ challengeType: 1 You can specify the lower and upper number of patterns with
let A3 = "haaah";
let A100 = "h" + "a".repeat(100) + "h";
let multipleHA = /ha{3}h/;
multipleHA.test(A4); // Returns false
multipleHA.test(A3); // Returns true
multipleHA.test(A100); // Returns false
quantity specifiers
using curly brackets. Sometimes you only want to specify the lower number of patterns with no upper limit.
To only specify the lower number of patterns, keep the first number followed by a comma.
For example, to match only the string "hah"
with the letter a
appearing at least 3
times, your regex would be /ha{3,}h/
.
-let A4 = "haaaah";+ +```js +let A4 = "haaaah"; +let A2 = "haah"; +let A100 = "h" + "a".repeat(100) + "h"; +let multipleA = /ha{3,}h/; +multipleA.test(A4); // Returns true +multipleA.test(A2); // Returns false +multipleA.test(A100); // Returns true +``` + ## Instructions diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/specify-upper-and-lower-number-of-matches.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/specify-upper-and-lower-number-of-matches.english.md index a49d3c0c16..ab0f92e32c 100644 --- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/specify-upper-and-lower-number-of-matches.english.md +++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/specify-upper-and-lower-number-of-matches.english.md @@ -9,7 +9,15 @@ challengeType: 1 Recall that you use the plus sign
let A2 = "haah";
let A100 = "h" + "a".repeat(100) + "h";
let multipleA = /ha{3,}h/;
multipleA.test(A4); // Returns true
multipleA.test(A2); // Returns false
multipleA.test(A100); // Returns true
+
to look for one or more characters and the asterisk *
to look for zero or more characters. These are convenient but sometimes you want to match a certain range of patterns.
You can specify the lower and upper number of patterns with quantity specifiers
. Quantity specifiers are used with curly brackets ({
and }
). You put two numbers between the curly brackets - for the lower and upper number of patterns.
For example, to match only the letter a
appearing between 3
and 5
times in the string "ah"
, your regex would be /a{3,5}h/
.
-let A4 = "aaaah";+ +```js +let A4 = "aaaah"; +let A2 = "aah"; +let multipleA = /a{3,5}h/; +multipleA.test(A4); // Returns true +multipleA.test(A2); // Returns false +``` + ## Instructions diff --git a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/use-capture-groups-to-search-and-replace.english.md b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/use-capture-groups-to-search-and-replace.english.md index 802e13a650..cf3ea24640 100644 --- a/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/use-capture-groups-to-search-and-replace.english.md +++ b/curriculum/challenges/english/02-javascript-algorithms-and-data-structures/regular-expressions/use-capture-groups-to-search-and-replace.english.md @@ -8,9 +8,21 @@ challengeType: 1
let A2 = "aah";
let multipleA = /a{3,5}h/;
multipleA.test(A4); // Returns true
multipleA.test(A2); // Returns false
.replace()
on a string. The inputs for .replace()
is first the regex pattern you want to search for. The second parameter is the string to replace the match or a function to do something.
-let wrongText = "The sky is silver.";+ +```js +let wrongText = "The sky is silver."; +let silverRegex = /silver/; +wrongText.replace(silverRegex, "blue"); +// Returns "The sky is blue." +``` + You can also access capture groups in the replacement string with dollar signs (
let silverRegex = /silver/;
wrongText.replace(silverRegex, "blue");
// Returns "The sky is blue."
$
).
-"Code Camp".replace(/(\w+)\s(\w+)/, '$2 $1');+ +```js +"Code Camp".replace(/(\w+)\s(\w+)/, '$2 $1'); +// Returns "Camp Code" +``` +
// Returns "Camp Code"
"the"
in the string "The dog chased the cat"
, you could use the following regular expression: /the/
. Notice that quote marks are not required within the regular expression.
JavaScript has multiple ways to use regexes. One way to test a regex is using the .test()
method. The .test()
method takes the regex, applies it to a string (which is placed inside the parentheses), and returns true
or false
if your pattern finds something or not.
-let testStr = "freeCodeCamp";+ +```js +let testStr = "freeCodeCamp"; +let testRegex = /Code/; +testRegex.test(testStr); +// Returns true +``` + ## Instructions
let testRegex = /Code/;
testRegex.test(testStr);
// Returns true