You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: ebook/01_var_let_const.md
+44-24Lines changed: 44 additions & 24 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,12 +1,14 @@
1
1
# Chapter 1: Var vs Let vs Const & the temporal dead zone
2
2
3
-
With the introduction of `let` and `const` in **ES6** we can know better define our variable depending on our needs. Let's have a look at the major differences between them.
3
+
With the introduction of `let` and `const` in **ES6**, we can now better define our variable depending on our needs. Let's have a look at the major differences between them.
4
+
5
+
4
6
5
7
## `Var`
6
8
7
-
`var` are **function scoped**, which means that if we declare them inside a `for` loop \(which is a **block** scope\) they will be available globally.
9
+
`var` are **function scoped**, which means that if we declare them inside a `for` loop (which is a **block** scope) they will be available globally.
8
10
9
-
```javascript
11
+
```javascript
10
12
for (var i =0; i <10; i++) {
11
13
varglobal="I am available globally";
12
14
}
@@ -24,13 +26,15 @@ console.log(functionScoped);
24
26
// ReferenceError: functionScoped is not defined
25
27
```
26
28
27
-
In the first example the value of `var` global leaked out of the block-scope and could be accessed from the global scope whereas in the second example `var` was confined inside a function-scope and we could not access it from outside.
29
+
In the first example the value of the `var` global leaked out of the block-scope and could be accessed from the global scope, whereas in the second example `var` was confined inside a function-scope and we could not access it from outside.
30
+
31
+
28
32
29
33
## `Let`
30
34
31
-
`let`\(and `const` are **block scoped** meaning that they will be available only inside of the block where they are declared and its sub-blocks.
35
+
`let` (and `const`) are **block scoped**, meaning that they will be available only inside of the block where they are declared and its sub-blocks.
32
36
33
-
```javascript
37
+
```javascript
34
38
// using `let`
35
39
let x ="global";
36
40
@@ -58,24 +62,31 @@ console.log(y);
58
62
// expected output: block-scoped
59
63
```
60
64
61
-
As you can see, when we assigned a new value to our `let` inside our block-scope it **did not** change the value in the global scope, whereas when did the same with our `var` it leaked outside of the block-scope and also change it in the global scope.
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 global scope, whereas when did the same with our `var` it leaked outside of the block-scope and also changed it in the global scope.
66
+
67
+
62
68
63
69
## `Const`
64
70
65
-
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 redeclared**.
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 redeclared**.
66
72
67
-
```javascript
73
+
74
+
```javascript
68
75
constconstant='I am a constant';
69
76
constant =" I can't be reassigned";
70
77
71
78
// Uncaught TypeError: Assignment to constant variable
72
79
```
73
80
74
-
**Important** This **does not** mean that **const are immutable**.
81
+
82
+
**Important**
83
+
This **does not** mean that **const are immutable**.
84
+
85
+
75
86
76
87
### The content of a `const` is an Object
77
88
78
-
```javascript
89
+
```javascript
79
90
constperson= {
80
91
name:'Alberto',
81
92
age:25,
@@ -84,13 +95,16 @@ const person = {
84
95
person.age=26;
85
96
86
97
// in this case no error will be raised, we are not re-assigning the variable but just one of its properties.
87
-
```
98
+
```
99
+
100
+
---
101
+
88
102
89
103
## The temporal dead zone
90
104
91
105
According to **MDN**:
92
106
93
-
> In ECMAScript 2015, let bindings are not subject to **Variable Hoisting**, which means that let declarations do not move to the top of the current execution context. Referencing the variable in the block before the initialization results in a ReferenceError \(contrary to a variable declared with var, which will just have the undefined value\). The variable is in a “temporal dead zone” from the start of the block until the initialization is processed.
107
+
> In ECMAScript 2015, let bindings are not subject to **Variable Hoisting**, which means that let declarations do not move to the top of the current execution context. Referencing the variable in the block before the initialization results in a ReferenceError (contrary to a variable declared with var, which will just have the undefined value). The variable is in a “temporal dead zone” from the start of the block until the initialization is processed.
`var` can be accessed **before** they are defined, but we can't access their **value**. `let` and `const` can't be accessed **before we define them**.
123
+
`var` can be accessed **before** they are defined, but we can't access their **value**.
124
+
`let` and `const` can't be accessed **before we define them**.
125
+
126
+
This happens because `var` are subject to **hoisting**, which means that they are processed before any code is executed. Declaring a `var` anywhere is equivalent to **declaring it at the top**. This is why we can still access the `var` but we can't yet see its content, hence the `undefined` result.
110
127
111
-
This happens because `var` are subject to **hoisting** which means that they are processed before any code is executed. Declaring a `var` anywhere is equivalent to **declaring it at the top**. This is why we can still access the `var` but we can't yet see its content, hence the `undefined` result.
128
+
129
+
---
130
+
112
131
113
132
## When to use `Var`, `Let` and `Const`
114
133
115
134
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.
116
135
117
136
The first opinion comes from [Mathias Bynes:](https://mathiasbynens.be/notes/es6-const)
118
137
119
-
* use `const` by default
120
-
* use `let` only if rebinding is needed.
121
-
*`var` should never be used in ES6.
122
138
123
-
The second opinion comes from [Kyle Simpson:](https://github.com/AlbertoMontalesi/JavaScript-ES6-for-beginners-ebook/tree/33fc6a922b67c3f7e105bd14b3828b77a67ebdb4/ebook/blog.getify.com/constantly-confusing-const/README.md)
139
+
- use `const` by default
140
+
- use `let` only if rebinding is needed.
141
+
-`var` should never be used in ES6.
124
142
125
-
* Use `var` for top-level variables that are shared across many \(especially larger\) scopes.
126
-
* Use `let` for localized variables in smaller scopes.
127
-
* Refactor `let` to `const` only after some code has to be written, and you're reasonably sure that you've got a case where there shouldn't be variable reassignment.
128
143
129
-
Which opinion to follow is entirely up to you. As always, do your own research and figure out which one you think is the best.
144
+
The second opinion comes from [Kyle Simpson:](blog.getify.com/constantly-confusing-const/)
130
145
131
-
You may want to [read this article](https://medium.com/@sbakkila/javascript-es-6-let-and-the-dreaded-temporal-dead-zone-85b89314d168) to understand how `let` affects your performances compared to `var` before you choose to follow either [Mathias Bynes](https://mathiasbynens.be/notes/es6-const) or [Kyle Simpson](https://github.com/AlbertoMontalesi/JavaScript-ES6-for-beginners-ebook/tree/33fc6a922b67c3f7e105bd14b3828b77a67ebdb4/ebook/blog.getify.com/constantly-confusing-const/README.md).
146
+
- Use `var` for top-level variables that are shared across many (especially larger) scopes.
147
+
- Use `let` for localized variables in smaller scopes.
148
+
- Refactor `let` to `const` only after some code has to be written, and you're reasonably sure that you've got a case where there shouldn't be variable reassignment.
149
+
150
+
Which opinion to follow is entirely up to you. As always, do your own research and figure out which one you think is the best.
132
151
152
+
You may want to [read this article](https://medium.com/@sbakkila/javascript-es-6-let-and-the-dreaded-temporal-dead-zone-85b89314d168) to understand how `let` affects your performances compared to `var` before you choose to follow either [Mathias Bynes](https://mathiasbynens.be/notes/es6-const) or [Kyle Simpson](blog.getify.com/constantly-confusing-const/).
To tell JavaScript that what's inside the curly braces is an **object literal** that we want to implicitly return we need to wrap everything inside parenthesis.
64
+
To tell JavaScript that what's inside the curly braces is an **object literal** that we want to implicitly return, we need to wrap everything inside parenthesis.
60
65
61
66
Writing `race` or `race:race` is the same.
62
67
68
+
69
+
63
70
## Arrow functions are anonymous
64
71
65
72
As you can see from the previous examples, arrow functions are **anonymous**.
66
73
67
74
If we want to have a name to reference them we can bind them to a variable:
68
75
69
-
```javascript
76
+
```javascript
70
77
constgreeting= (name) =>`hello ${name}`;
71
78
72
79
greeting("Tom");
73
80
```
74
81
82
+
83
+
84
+
75
85
## Arrow function and the `this` keyword
76
86
77
-
You need to be careful when using arrow functions in conjunction with the this keyword as they behave differently from normal functions.
87
+
You need to be careful when using arrow functions in conjunction with the this keyword, as they behave differently from normal functions.
78
88
79
89
When you use an arrow function, the `this` keyword is inherited from the parent scope.
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, trowing this error:
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, trowing this error:
What if we don't want to pass the parameter at all, like this:
15
15
16
-
```javascript
16
+
```javascript
17
17
// The 0.15 will be bound to the second argument, tax even if in our intention it was to set 0.15 as the tip
18
18
calculatePrice(100, 0.15)
19
19
```
20
20
21
21
We can solve by doing this:
22
22
23
-
```javascript
23
+
```javascript
24
24
// In this case 0.15 will be bound to the tip
25
25
calculatePrice(100, undefined, 0.15)
26
26
```
@@ -29,11 +29,10 @@ It works, but it's not very nice, how to improve it?
29
29
30
30
With **destructuring** we can write this:
31
31
32
-
```javascript
32
+
```javascript
33
33
constBill=calculatePrice({ tip:0.15, total:150});
34
34
```
35
35
36
36
We don't even have to pass the parameters in the same order as when we declared our function, since we are calling them the same way as the arguments JavaScript will know how to match them.
37
37
38
-
Don't worry about destructuring, we will talk about it in a later chapter.
39
-
38
+
Don't worry about destructuring, we will talk about it in a later chapter.
0 commit comments