Skip to content

Commit 209e101

Browse files
Major update and fixes
1 parent 7f570e6 commit 209e101

22 files changed

+596
-256
lines changed

ebook/01_var_let_const.md

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
# Chapter 1: Var vs Let vs Const & the temporal dead zone
22

3-
With the introduction of `let` and `const` in **ES6**, we can now better define our variables depending on our needs. During our JavaScript primer we looked at the basic differences between these 3 keywords, now we will go into more detail.
3+
With the introduction of `let` and `const` in **ES6**, we can now better define our variables depending on our needs. During our `JavaScript` primer we looked at the basic differences between these 3 keywords, now we will go into more detail.
44

55
 
66

77
## `Var`
88

99
Variables declared with the `var` keyword are **function scoped**, which means that if we declare them inside a `for` loop (which is a **block** scope) they will be available even outside of it.
1010

11-
``` javascript
11+
```JavaScript
1212
for (var i = 0; i < 10; i++) {
1313
var leak = "I am available outside of the loop";
1414
}
@@ -34,7 +34,7 @@ In the first example the value of the `var` leaked out of the block-scope and co
3434

3535
Variables declared with the `let` (and `const`) keyword are **block scoped**, meaning that they will be available only inside of the block where they are declared and its sub-blocks.
3636

37-
``` javascript
37+
```JavaScript
3838
// using `let`
3939
let x = "global";
4040

@@ -62,29 +62,29 @@ console.log(y);
6262
// expected output: block-scoped
6363
```
6464

65-
As you can see, when we assigned a new value to our `let` inside our block-scope, it **did not** change its value in the outer scope, whereas when did the same with our `var` it leaked outside of the block-scope and also changed it in the outer scope.
65+
As you can see, when we assigned a new value to the variable declared with `let` inside our block-scope, it **did not** change its value in the outer scope. Whereas, when we did the same with the variable declared with var, it leaked outside of the block-scope and also changed it in the outer scope.
6666

6767
&nbsp;
6868

6969
## `Const`
7070

71-
Similarly to `let`, `const` are **block-scoped**, but they differ in the fact that their value **can't change through re-assignment or can't be re-declared**.
71+
Similarly to `let`, variables declared with `const` are also **block-scoped**, but they differ in the fact that their value **can't change through re-assignment or can't be re-declared**.
7272

73-
``` javascript
73+
```JavaScript
7474
const constant = 'I am a constant';
7575
constant = " I can't be reassigned";
7676

7777
// Uncaught TypeError: Assignment to constant variable
7878
```
7979

80-
**Important**
81-
This **does not** mean that **const are immutable**.
80+
>**Important**:
81+
This **does not** mean that variables declared with `const` are immutable.
8282

8383
&nbsp;
8484

8585
### The content of a `const` is an Object
8686

87-
``` javascript
87+
```JavaScript
8888
const person = {
8989
name: 'Alberto',
9090
age: 25,
@@ -99,9 +99,9 @@ In this case we are not reassigning the whole variable but just one of its prope
9999

100100
---
101101

102-
Note: We can still freeze the const object, which will not change the contents of the object (but trying to change the values of object JavaScript will not throw any error)
102+
>Note: We can still freeze the `const` object, which will not change the contents of the object (but trying to change the values of object `JavaScript` will not throw any error)
103103
104-
``` javascript
104+
```JavaScript
105105
const person = {
106106
name: 'Alberto',
107107
age: 25,
@@ -144,19 +144,19 @@ let j = "I am a let";
144144

145145
Despite what you may read on other sources, both `var` and `let`(and `const`) are subject to **hoisting** which means that they are processed before any code is executed and lifted up to the top of their scope (whether it's global or block).
146146

147-
The main differences lays in the fact that `var` can still be accessed before they are defined, causing the value to be `undefined` while on the other hand, `let` variables sit in a **temporal dead zone** until they are declared, causing an error when accessed before initialization which makes it easier to debug code rather than having an `undefined` as the result.
147+
The main differences lie in the fact that `var` can still be accessed before they are defined. This causes the value to be `undefined`. While on the other hand, `let` lets the variables sit in a **temporal dead zone** until they are declared. And this causes an error when accessed before initialization, which makes it easier to debug code rather than having an `undefined` as the result.
148148

149149
---
150150
&nbsp;
151151

152152
## When to use `Var`, `Let` and `Const`
153153

154-
There is no rule stating where to use each of them and people have different opinions. Here I am going to present to you two opinions from popular developers in the JavaScript community.
154+
There is no rule stating where to use each of them and people have different opinions. Here I am going to present to you two opinions from popular developers in the `JavaScript` community.
155155

156156
The first opinion comes from [Mathias Bynes:](https://mathiasbynens.be/notes/es6-const)
157157

158-
- use `const` by default
159-
- use `let` only if rebinding is needed.
158+
- Use `const` by default
159+
- Use `let` only if rebinding is needed.
160160
- `var` should never be used in ES6.
161161

162162
The second opinion comes from [Kyle Simpson:](https://me.getify.com/)

ebook/02_arrow_functions.md

Lines changed: 66 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,32 +5,32 @@
55
ES6 introduced fat arrows (`=>`) as a way to declare functions.
66
This is how we would normally declare a function in ES5:
77

8-
``` javascript
9-
var greeting = function(name) {
8+
```JavaScript
9+
const greeting = function(name) {
1010
return "hello " + name;
1111
}
1212
```
1313

1414
The new syntax with a fat arrow looks like this:
1515

16-
``` javascript
17-
const greeting = (name) => {
16+
```JavaScript
17+
var greeting = (name) => {
1818
return `hello ${name}`;
1919
}
2020
```
2121

2222
We can go further, if we only have one parameter we can drop the parenthesis and write:
2323

24-
``` javascript
25-
const greeting = name => {
24+
```JavaScript
25+
var greeting = name => {
2626
return `hello ${name}`;
2727
}
2828
```
2929

3030
If we have no parameter at all we need to write empty parenthesis like this:
3131

32-
``` javascript
33-
const greeting = () => {
32+
```JavaScript
33+
var greeting = () => {
3434
return "hello";
3535
}
3636
```
@@ -41,7 +41,7 @@ const greeting = () => {
4141

4242
With arrow functions we can skip the explicit `return` and return like this:
4343

44-
``` javascript
44+
```JavaScript
4545
const greeting = name => `hello ${name}`;
4646
```
4747

@@ -64,9 +64,9 @@ const arrowFunction = (name) => {
6464
}
6565
```
6666

67-
Let's say we want to implicitly return an **object literal**, we would do like this:
67+
Let's say we want to implicitly return an **object literal**, we would do it like this:
6868

69-
``` javascript
69+
```JavaScript
7070
const race = "100m dash";
7171
const runners = [ "Usain Bolt", "Justin Gatlin", "Asafa Powell" ];
7272

@@ -78,7 +78,9 @@ console.log(results);
7878
// {name: "Asafa Powell", race: "100m dash", place: 3}]
7979
```
8080

81-
To tell JavaScript what's inside the curly braces is an **object literal** we want to implicitly return, we need to wrap everything inside parenthesis.
81+
In this example, we are using the `map` function to iterate over the array `runners`. The first argument is the current item in the array and the `i` is the index of it. For each item in the array we are then adding into `results` an Object containing the properties `name`, `race`, and `place`.
82+
83+
To tell `JavaScript` what's inside the curly braces is an **object literal** we want to implicitly return, we need to wrap everything inside parenthesis.
8284

8385
Writing `race` or `race: race` is the same.
8486

@@ -90,7 +92,7 @@ As you can see from the previous examples, arrow functions are **anonymous**.
9092

9193
If we want to have a name to reference them we can bind them to a variable:
9294

93-
``` javascript
95+
```JavaScript
9496
const greeting = name => `hello ${name}`;
9597

9698
greeting("Tom");
@@ -106,7 +108,19 @@ When you use an arrow function, the `this` keyword is inherited from the parent
106108

107109
This can be useful in cases like this one:
108110

109-
``` javascript
111+
```html
112+
<div class="box open">
113+
This is a box
114+
</div>
115+
```
116+
117+
```css
118+
.opening {
119+
background-color:red;
120+
}
121+
```
122+
123+
```JavaScript
110124
// grab our div with class box
111125
const box = document.querySelector(".box");
112126
// listen for a click event
@@ -115,59 +129,80 @@ box.addEventListener("click", function() {
115129
this.classList.toggle("opening");
116130
setTimeout(function(){
117131
// try to toggle again the class
118-
this.classList.toggle("open");
119-
});
132+
this.classList.toggle("opening");
133+
},500);
120134
});
121135
```
122136

123137
The problem in this case is that the first `this` is bound to the `const` box but the second one, inside the `setTimeout`, will be set to the `Window` object, throwing this error:
124138

125-
``` javascript
139+
```JavaScript
126140
Uncaught TypeError: cannot read property "toggle" of undefined
127141
```
128142

129143
Since we know that **arrow functions** inherit the value of `this` from the parent scope, we can re-write our function like this:
130144

131-
``` javascript
132-
// grab our div with class box
145+
```JavaScript
133146
const box = document.querySelector(".box");
134147
// listen for a click event
135-
box.addEventListener("click", function () {
148+
box.addEventListener("click", function() {
136149
// toggle the class opening on the div
137150
this.classList.toggle("opening");
138-
setTimeout(() => {
151+
setTimeout(()=>{
139152
// try to toggle again the class
140-
this.classList.toggle("open");
141-
});
153+
this.classList.toggle("opening");
154+
},500);
142155
});
143156
```
144157

145158
Here, the second `this` will inherit from its parent, and will be set to the `const` box.
146159

160+
Running the example code you should see our `div` turning red for just half a second.
161+
147162
&nbsp;
148163

149164
## When you should avoid arrow functions
150165

151166
Using what we know about the inheritance of the `this` keyword we can define some instances where you should **not** use arrow functions.
152167

153-
The next 2 examples show when to be careful using `this` inside of arrows.
168+
The next two examples show when to be careful using `this` inside of arrows.
169+
170+
#### Example 1
154171

155-
``` javascript
172+
```JavaScript
156173
const button = document.querySelector("btn");
157174
button.addEventListener("click", () => {
158175
// error: *this* refers to the `Window` Object
159176
this.classList.toggle("on");
160177
})
161178
```
162179

163-
``` javascript
164-
const person = {
180+
&nbsp;
181+
182+
#### Example 2
183+
184+
```JavaScript
185+
const person1 = {
186+
age: 10,
187+
grow: function() {
188+
this.age++;
189+
console.log(this.age);
190+
}
191+
}
192+
193+
person1.grow();
194+
// 11
195+
196+
const person2 = {
165197
age: 10,
166198
grow: () => {
167199
// error: *this* refers to the `Window` Object
168200
this.age++;
201+
console.log(this.age);
169202
}
170203
}
204+
205+
person2.grow();
171206
```
172207

173208
Another difference between Arrow functions and normal functions is the access to the `arguments object`.
@@ -193,15 +228,15 @@ Let's have a look at this example with our previous list of runners:
193228
```javascript
194229
const showWinner = () => {
195230
const winner = arguments[0];
196-
return `${winner} was the winner`
231+
console.log(`${winner} was the winner`)
197232
}
198233

199234
showWinner( "Usain Bolt", "Justin Gatlin", "Asafa Powell" )
200235
```
201236

202237
This code will return:
203238

204-
``` javascript
239+
```JavaScript
205240
ReferenceError: arguments is not defined
206241
```
207242

@@ -214,7 +249,7 @@ Example with **arrow function**:
214249
```javascript
215250
const showWinner = (...args) => {
216251
const winner = args[0];
217-
return `${winner} was the winner`
252+
console.log(`${winner} was the winner`)
218253
}
219254
showWinner("Usain Bolt", "Justin Gatlin", "Asafa Powell" )
220255
// "Usain Bolt was the winner"
@@ -225,7 +260,7 @@ Example with **function**:
225260
```javascript
226261
const showWinner = function() {
227262
const winner = arguments[0];
228-
return `${winner} was the winner`
263+
console.log(`${winner} was the winner`)
229264
}
230265
showWinner("Usain Bolt", "Justin Gatlin", "Asafa Powell")
231266
// "Usain Bolt was the winner"

ebook/03_default_function_arguments.md

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,15 @@ With **destructuring** we can write this:
8181
function calculatePrice({
8282
total = 0,
8383
tax = 0.1,
84-
tip = 0.05} = {} ){
84+
tip = 0.05} = {}){
8585
return total + (total * tax) + (total * tip);
8686
}
8787

8888
const bill = calculatePrice({ tip: 0.15, total:150 });
8989
// 187.5
90+
```
9091

91-
We made the argument of our function an Object and when calling the function we don't even have to worry about the order of the parameters because they will be matched based on their key.
92+
We made the argument of our function an Object. When calling the function, we dont even have to worry about the order of the parameters because they are matched based on their key.
9293

9394
In the example above the default value for *tip* was 0.05 and we overwrote it with 0.15 but we didn't give a value to tax which remained the default 0.1.
9495

@@ -104,7 +105,7 @@ Notice this detail:
104105

105106
If we don't default our argument Object to an empty Object, and we were to try and run `calculatePrice()` we would get:
106107

107-
``` javascript
108+
```JavaScript
108109
Cannot destructure property `total` of 'undefined' or 'null'.
109110
```
110111

@@ -121,4 +122,19 @@ calculatePrice(undefined)
121122

122123
No matter what we passed, the argument was defaulted to an `Object` which had three default properties of total, tax and tip.
123124

125+
```javascript
126+
function calculatePrice({
127+
total = 0,
128+
tax = 0.1,
129+
tip = 0.05}){
130+
return total + (total * tax) + (total * tip);
131+
}
132+
calculatePrice({});
133+
// cannot read property `total` of 'undefined' or 'null'.
134+
calculatePrice();
135+
// cannot read property `total` of 'undefined' or 'null'.
136+
calculatePrice(undefined)
137+
// cannot read property `total` of 'undefined' or 'null'.
138+
```
139+
124140
Don't worry about destructuring, we will talk about it in Chapter 10.

0 commit comments

Comments
 (0)