Skip to content

Commit ea909b1

Browse files
committed
Merge branch 'feature/Day_7_contents' into develop
2 parents a96aef8 + 0411dc4 commit ea909b1

8 files changed

+361
-15
lines changed

README.md

+8-13
Original file line numberDiff line numberDiff line change
@@ -119,25 +119,20 @@ A lot of information has been written about JavaScript and EcmaScript since both
119119
- Relative Concepts Readings
120120
- Preliminary practice
121121
- Exercises
122-
- DAY 7
122+
- [DAY 7](/day_07.md)
123123
- `this` Keyword
124-
- <https://github.com/getify/You-Dont-Know-JS/blob/master/this%20%26%20object%20prototypes/ch1.md>
125-
- <https://github.com/getify/You-Dont-Know-JS/blob/master/this%20%26%20object%20prototypes/ch2.md>
126-
- <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this>
127-
- BIND
128-
- APPLY
129-
- CALL
124+
- Introduction
125+
- Resolving `this`
126+
- Explicitly binding `this` through prototype methods
127+
- `Function.prototype.bind()`
128+
- `Function.prototype.apply()`
129+
- `Function.prototype.call()`
130130
- Strict mode
131131
- What happens on strict mode?
132132
- Semantic Differences
133133
- Arrow Functions
134-
- ...
135-
- ...
136-
- .. good practices
137134
- Generators
138-
- ..
139-
- ..
140-
- .. good practices
135+
- Exercises
141136
- DAY 8
142137
- Classes
143138
- <https://www.ecma-international.org/ecma-262/6.0/#sec-class-definitions>

day_07.md

+351
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,351 @@
1+
# [A walk in JavaScript](/README.md)
2+
3+
## DAY 7
4+
5+
- `this` Keyword
6+
- Introduction
7+
- Resolving `this`
8+
- Explicitly binding `this` through prototype methods
9+
- `Function.prototype.bind()`
10+
- `Function.prototype.apply()`
11+
- `Function.prototype.call()`
12+
- Strict mode
13+
- What happens on strict mode?
14+
- Semantic Differences
15+
- Arrow Functions
16+
- Generators
17+
- Exercises
18+
19+
## `this` Keyword
20+
21+
Over and over again I see engineers struggling with `this` topic; is so weird!! Long ago I found myself in the same situation, like, being writing code for many years and still ... never took the time to really understand `this` when `this` is one of the most important and powerful features in JavaScript!
22+
Engineers we feel so frustrated about `this` that there's even a joke for `this`!
23+
24+
> JavaScript makes me want to flip the table and say "F*** this shit", but I can never be sure what **`this`** refers to.
25+
26+
The good things came when I took the responsibility of `this` and accepted the guilt was entirely mine.
27+
28+
Why this intro? because there are tons of articles regarding `this` but everything about `this` was written by **Kyle Simpson** who dedicated a whole book for `this` topic , so we're gonna read and study it until we breath `this`.
29+
30+
### Resolving `this`
31+
32+
Let's take a look at the following chapters of **You Don't Know JS: this & Object Prototypes - 1st Edition**
33+
34+
- [Chapter 1: this Or That?](https://github.com/getify/You-Dont-Know-JS/blob/1st-ed/this%20%26%20object%20prototypes/ch1.md)
35+
- [Chapter 2: this All Makes Sense Now!](https://github.com/getify/You-Dont-Know-JS/blob/1st-ed/this%20%26%20object%20prototypes/ch2.md)
36+
- [Chapter 5: Prototypes](https://github.com/getify/You-Dont-Know-JS/blob/1st-ed/this%20%26%20object%20prototypes/ch5.md)
37+
- [Chapter 6: Behavior Delegation](https://github.com/getify/You-Dont-Know-JS/blob/1st-ed/this%20%26%20object%20prototypes/ch6.md)
38+
39+
Now let's see how ECMAScript specifies the mechanism to resolve `this`.
40+
41+
- [GetThisEnvironment ( )](https://www.ecma-international.org/ecma-262/6.0/#sec-getthisenvironment)
42+
- [ResolveThisBinding ( )](https://www.ecma-international.org/ecma-262/6.0/#sec-resolvethisbinding)
43+
44+
In the other hand, MDN describes `this` on the Operators section
45+
46+
- [MDN - *this*](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this)
47+
48+
### Explicitly binding `this` through prototype methods
49+
50+
Now we've learned that `this` has specific rules and it's resolved at run-time, and we saw that the `function` prototype has 3 methods to explicitly define where to point when `this` needs to be resolved during it's execution.
51+
52+
- [Function.prototype.bind()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind)
53+
- [Function.prototype.apply()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply)
54+
- [Function.prototype.call()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call)
55+
56+
Now, there's a catch!!! it seems that depending on a thing called **mode**, that depending on it's [strictness](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode) or [non-strictness](https://developer.mozilla.org/en-US/docs/Glossary/Sloppy_mode) (a.k.a. Sloppy) it'll alter the semantics and behavior of many things including `this`.
57+
58+
---
59+
60+
## Strict Mode
61+
62+
- [MDN - Strict Mode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode)
63+
- [MDN - Transitioning to Strict Mode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode/Transitioning_to_strict_mode)
64+
- [ECMAScript 5.1 - Strict Mode](http://www.ecma-international.org/ecma-262/5.1/#sec-10.1.1)
65+
[ECMAScript 2015 - Strict Mode](http://www.ecma-international.org/ecma-262/6.0/#sec-strict-mode-code)
66+
- [The ECMAScript 2016 change you probably don't know](https://humanwhocodes.com/blog/2016/10/the-ecmascript-2016-change-you-probably-dont-know/)
67+
- [Speaking JavaScript - Chp.7 Strict Mode" - by Dr. Axel Rauschmayer](http://speakingjs.com/es5/ch07.html#strict_mode)
68+
69+
### What happens on strict mode?
70+
71+
#### TL;DR
72+
73+
1. Eliminates some JavaScript `silent errors` by changing them `to throw errors`.
74+
2. Fixes mistakes that make it difficult for JavaScript engines to perform optimizations: strict mode code can sometimes be made to run faster than identical code that's not strict mode.
75+
3. Prohibits some syntax likely to be defined in future versions of ECMAScript.
76+
77+
### Semantic differences
78+
79+
- `this` resolution won't propagate to the global scope, thus for a strict mode function, the specified this is not boxed into an object, and if unspecified, this will be `undefined`
80+
- arguments doesn't alias named function arguments
81+
- `eval` doesn't create a new variable in the scope from which it was called, `eval` of strict mode code does not introduce new variables into the surrounding scope.
82+
83+
When adding `'use strict';` the following cases will throw an Error:
84+
85+
- SyntaxError
86+
- Octal syntax `var n = 023;`
87+
- `with` statement
88+
- Using delete on a variable name `delete myVariable`;
89+
- Using `eval` or `arguments` as variable or function argument name
90+
- Using one of the newly reserved keywords (in prevision for ECMAScript 2015):
91+
- `implements`,
92+
- `interface`,
93+
- `let`,
94+
- `package`,
95+
- `private`,
96+
- `protected`,
97+
- `public`,
98+
- `static`,
99+
- and `yield`
100+
- Escape characters are not allowed `var y = \010;`
101+
- Declaring function in blocks `if (a < b) { function f() {} }`
102+
- Obvious errors
103+
- Declaring twice the same name for a property name in an object literal `{a: 1, b: 3, a: 7}` This is no longer the case in ECMAScript 2015 (bug 1041128).
104+
- Declaring two function parameters with the same name function `f(a, b, b) {}`
105+
- TypeError
106+
- Writing to a get-only property is not allowed
107+
- Writing to a read-only property is not allowed
108+
- Deleting an undeletable property is not allowed `delete Object.prototype`
109+
- Setting properties on primitive values `false.true = '';` , `(14).sailing = 'home';` , `'with'.you = 'far away';`
110+
- Runtime errors
111+
- Setting a value to an undeclared variable
112+
- Trying to delete a non-configurable property
113+
- Poisoned arguments and function properties, e.g. accessing `arguments.callee`, `arguments.caller`, `anyFunction.caller`, or `anyFunction.arguments`
114+
- ReferenceError
115+
- Using a variable, without declaring it
116+
117+
---
118+
119+
## Arrow Functions
120+
121+
> An arrow function expression is a syntactically compact alternative to a regular function expression, although without its own bindings to the this, arguments, super, or new.target keywords. Arrow function expressions are ill suited as methods, and they cannot be used as constructors.
122+
>
123+
> Source: [MDN - Arrow Functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)
124+
125+
### Syntax
126+
127+
```javascript
128+
(param1, param2, …, paramN) => { statements }
129+
(param1, param2, …, paramN) => expression
130+
// equivalent to: => { return expression; }
131+
132+
// Parentheses are optional when there's only one parameter name:
133+
(singleParam) => { statements }
134+
singleParam => { statements }
135+
136+
// The parameter list for a function with no parameters should be written with a pair of parentheses.
137+
() => { statements }
138+
139+
// Parenthesize the body of a function to return an object literal expression:
140+
params => ({foo: bar})
141+
142+
// Rest parameters and default parameters are supported
143+
(param1, param2, ...rest) => { statements }
144+
(param1 = defaultValue1, param2, …, paramN = defaultValueN) => {
145+
statements }
146+
147+
// Destructuring within the parameter list is also supported
148+
var f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
149+
f(); // 6
150+
151+
```
152+
153+
One of the most expected and misused features of ES6 is the Arrow Function. Undoubtedly powerful it might also derive in a headache if you don't really know how they work and which are the differences between the full body notation and the arrow notation.
154+
155+
Let's take a look at [YDKJS - ES6 & Beyond - chapter 2](https://github.com/getify/You-Dont-Know-JS/blob/1st-ed/es6%20%26%20beyond/ch2.md#arrow-functions)
156+
157+
---
158+
159+
## Generators
160+
161+
So far we've seen (except for the iterators) only **[run-to-completion](https://en.wikipedia.org/wiki/Run_to_completion_scheduling)** examples of code. It means, "the execution won't stop until it's done or fails".
162+
What if I tell you there's a feature that let you define a function capable of being paused midway and resumed later?
163+
164+
Together with [`iterators`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#The_iterator_protocol) ES6 introduced something called `generators`.
165+
166+
> The Generator object is returned by a [generator function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*) and it conforms to both the [iterable protocol](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#The_iterable_protocol) and the [iterator protocol](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#The_iterator_protocol).
167+
168+
There are 2 ways to create a [generator object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator)
169+
170+
- [function* expression](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*)
171+
172+
```javascript
173+
function* name([param[, param[, ... param]]]) {
174+
statements
175+
}
176+
```
177+
178+
- [GeneratorFunction constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/GeneratorFunction)
179+
180+
```javascript
181+
let GeneratorFunction = Object.getPrototypeOf(function*(){}).constructor
182+
let myGenerator = new GeneratorFunction ([arg1[, arg2[, ...argN]],] functionBody)
183+
```
184+
185+
> **Note** that GeneratorFunction is **not a global object**.
186+
>
187+
> `generator` function objects created with the `GeneratorFunction` constructor are parsed when the function is created. This is less efficient than declaring a generator function with a `function* expression` and calling it within your code, because such functions are parsed with the rest of the code.
188+
>
189+
> Source: [MDN GeneratorFunction](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/GeneratorFunction)
190+
191+
Since this is a particularly complex topic, with several nuances, let's try to understand them through examples:
192+
193+
### Example of execution sequence
194+
195+
```javascript
196+
/**
197+
*
198+
* @param {number} initialValue
199+
* @returns {Object} Generator
200+
*/
201+
function* bottlesOfBeer (initialValue) {
202+
let bob = initialValue;
203+
let lastMessage = `No more bottles of beer on the wall, no more bottles of beer.
204+
Go to the store and buy some more, ${bob} bottles of beer on the wall.`;
205+
206+
while (true) {
207+
console.log(`${bob} bottles of beer on the wall, ${bob} bottles of beer.`);
208+
209+
yield bob--;
210+
211+
console.log(`Take one down and pass it around, ${bob} bottles of beer on the wall.`);
212+
213+
if (bob < 1) {
214+
bob = initialValue;
215+
console.log(lastMessage);
216+
}
217+
}
218+
}
219+
220+
let bob = bottlesOfBeer(100);
221+
222+
bob.next();
223+
// log -> 5 bottles of beer on the wall, 5 bottles of beer.
224+
// statement completion value -> {value: 5, done: false}
225+
226+
bob.next();
227+
// log -> Take one down and pass it around, 4 bottles of beer on the wall.
228+
// 4 bottles of beer on the wall, 4 bottles of beer.
229+
// statement completion value -> {value: 4, done: false}
230+
231+
// ... 3 more calls
232+
233+
bob.next();
234+
// log -> Take one down and pass it around, 0 bottles of beer on the wall.
235+
// No more bottles of beer on the wall, no more bottles of beer.
236+
// Go to the store and buy some more, 5 bottles of beer on the wall.
237+
// 5 bottles of beer on the wall, 5 bottles of beer.
238+
// statement completion value -> {value: 5, done: false}
239+
240+
// guess what happens now?
241+
242+
```
243+
244+
### Passing values through `next`
245+
246+
```javascript
247+
/**
248+
*
249+
* @returns {Object} Generator
250+
*/
251+
function* passingValToNext () {
252+
let val = 10;
253+
254+
while (true) {
255+
console.log(`UP val=${val}`);
256+
257+
val = yield val + 10;
258+
259+
console.log(`DOWN val=${val}`);
260+
}
261+
}
262+
263+
let pvtn = passingValToNext();
264+
// statement completion value -> passingValToNext {<suspended>}
265+
266+
pvtn.next(2);
267+
// log -> UP val=10
268+
// statement completion value -> {value: 20, done: false}
269+
270+
pvtn.next(7);
271+
// log -> DOWN val=7
272+
// log -> UP val=7
273+
// statement completion value -> {value: 17, done: false}
274+
275+
// WAIT! WHAT??!!!!
276+
// how does it work?
277+
278+
```
279+
280+
### Sample combining initial value and passing value to next
281+
282+
```javascript
283+
/**
284+
*
285+
* @param {Number} expectedTotal
286+
* @returns {Object} Generator
287+
*/
288+
function* calculateDownloadProgress (expectedTotal) {
289+
let totalDownloaded = 0;
290+
let newItems = 0;
291+
292+
while (true) {
293+
totalDownloaded += newItems || 0; // lazy verification for the value passed by `next`
294+
295+
let percent = ((totalDownloaded / expectedTotal) * 100).toFixed(2);
296+
297+
newItems = yield `${percent}%`;
298+
}
299+
}
300+
301+
let progress = calculateDownloadProgress(1024);
302+
// statement completion value -> undefined
303+
progress.next()
304+
// statement completion value -> {value: "0.00%", done: false}
305+
progress.next(15)
306+
// statement completion value -> {value: "1.46%", done: false}
307+
progress.next(500)
308+
// statement completion value -> {value: "50.29%", done: false}
309+
```
310+
311+
### DIY
312+
313+
```javascript
314+
/**
315+
*
316+
* @returns {Object} Generator
317+
*/
318+
function* spinGen() {
319+
while(true){
320+
yield* ['\\', '|', '/', '--'];
321+
}
322+
}
323+
324+
// now you add the code to see the output
325+
```
326+
327+
Let's take some time to read and discuss:
328+
329+
- [ECMAScript Generator Function](https://www.ecma-international.org/ecma-262/6.0/#sec-generatorfunction)
330+
- [YDKJS - ES6 & Beyond - CH3 - Generators](https://github.com/getify/You-Dont-Know-JS/blob/1st-ed/es6%20%26%20beyond/ch3.md#generators) - by Kyle Simpson
331+
- [The Basics Of ES6 Generators](https://davidwalsh.name/es6-generators) - By Kyle Simpson
332+
- [2ality - ES6 generators in depth](https://2ality.com/2015/03/es6-generators.html) - by Dr. Axel Rauschmayer
333+
334+
---
335+
336+
## Exercises
337+
338+
Let's open our test files:
339+
340+
- [this](/src/day_07/this.test.js)
341+
- [strict mode](/src/day_07/strictMode.test.js)
342+
- [arrow functions](/src/day_07/arrowFunctions.test.js)
343+
- [generators](/src/day_07/generators.test.js)
344+
345+
Now open your terminal.
346+
347+
1. Make sure you're at the project location
348+
2. If you didn't install all the packages yet then run `npm i` for a fresh dependency install, or `npm ci` for an installation based on the lock file.
349+
3. Type `npm run test:watch`, this will start running your tests every time you make a change.
350+
351+
**Our task is to make ALL our DAY 7 tests pass ;)**

package-lock.json

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)