Skip to content

Commit 7912e05

Browse files
committed
Resolve conflicts + update files.
1 parent 8266f75 commit 7912e05

File tree

6 files changed

+35
-125
lines changed

6 files changed

+35
-125
lines changed

1-js/01-getting-started/1-intro/article.md

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -106,20 +106,12 @@ Ferramentas modernas tornam a transpilação muito rápida e transparente, permi
106106

107107
Exemplos de tais linguagens:
108108

109-
<<<<<<< HEAD
110109
- [CoffeeScript](http://coffeescript.org/) é um "açúcar sintático" para JavaScript. Ele introduz uma sintaxe mais curta, permitindo-nos escrever um código mais claro e preciso. Normalmente, Ruby devs gostam dele.
111110
- [TypeScript](http://www.typescriptlang.org/) está concentrado em adicionar "estritos tipos de dados" para simplificar o desenvolvimento e suporte de sistemas complexos. É desenvolvido pela Microsoft.
112111
- [Flow](http://flow.org/) também adiciona tipos de dados, mas de uma forma diferente. Desenvolvido pela Facebook.
113-
- [Dart](https://www.dartlang.org/) é uma linguagem autônoma que tem seu próprio interpretador que roda em ambientes fora do navegador (como aplicativos móveis), mas também pode ser transpilada para JavaScript. Desenvolvido pela Google.
112+
- [Dart](https://www.dartlang.org/) é uma linguagem autônoma que tem seu próprio interpretador que roda em ambientes fora do navegador (como aplicativos móveis), mas também pode ser transpilada para JavaScript. Desenvolvida pela Google.
114113
- [Brython](https://brython.info/) é um transpilador de Python para JavaScript que permite escrever aplicativos em puro Python, sem JavaScript.
115-
=======
116-
- [CoffeeScript](http://coffeescript.org/) is a "syntactic sugar" for JavaScript. It introduces shorter syntax, allowing us to write clearer and more precise code. Usually, Ruby devs like it.
117-
- [TypeScript](http://www.typescriptlang.org/) is concentrated on adding "strict data typing" to simplify the development and support of complex systems. It is developed by Microsoft.
118-
- [Flow](http://flow.org/) also adds data typing, but in a different way. Developed by Facebook.
119-
- [Dart](https://www.dartlang.org/) is a standalone language that has its own engine that runs in non-browser environments (like mobile apps), but also can be transpiled to JavaScript. Developed by Google.
120-
- [Brython](https://brython.info/) is a Python transpiler to JavaScript that enables the writing of applications in pure Python without JavaScript.
121-
- [Kotlin](https://kotlinlang.org/docs/js-overview.html) is a modern, concise and safe programming language that can target the browser or Node.
122-
>>>>>>> 039716de8a96f49b5fccd7aed5effff2e719dfe5
114+
- [Kotlin](https://kotlinlang.org/docs/js-overview.html) é uma linguagem de programação moderna, concisa e segura, que pode ser usada no navegador ou no Node.
123115

124116
Há mais. Claro que, mesmo que usemos uma dessas linguagens transpiladas, também devemos saber JavaScript para entender o que estamos fazendo.
125117

1-js/05-data-types/02-number/article.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Imagine we need to write 1 billion. The obvious way is:
1616
let billion = 1000000000;
1717
```
1818

19-
But in real life we usually avoid writing a long string of zeroes as it's easy to mistype. Also, we are lazy. We will usually write something like `"1bn"` for a billion or `"7.3bn"` for 7 billion 300 million. The same is true for most large numbers.
19+
But in real life, we usually avoid writing a long string of zeroes as it's easy to mistype. Also, we are lazy. We will usually write something like `"1bn"` for a billion or `"7.3bn"` for 7 billion 300 million. The same is true for most large numbers.
2020

2121
In JavaScript, we shorten a number by appending the letter `"e"` to the number and specifying the zeroes count:
2222

@@ -180,7 +180,7 @@ There are two ways to do so:
180180

181181
## Imprecise calculations
182182

183-
Internally, a number is represented in 64-bit format [IEEE-754](http://en.wikipedia.org/wiki/IEEE_754-1985), so there are exactly 64 bits to store a number: 52 of them are used to store the digits, 11 of them store the position of the decimal point (they are zero for integer numbers), and 1 bit is for the sign.
183+
Internally, a number is represented in 64-bit format [IEEE-754](https://en.wikipedia.org/wiki/IEEE_754-2008_revision), so there are exactly 64 bits to store a number: 52 of them are used to store the digits, 11 of them store the position of the decimal point (they are zero for integer numbers), and 1 bit is for the sign.
184184

185185
If a number is too big, it would overflow the 64-bit storage, potentially giving an infinity:
186186

@@ -208,15 +208,15 @@ Ouch! There are more consequences than an incorrect comparison here. Imagine you
208208

209209
But why does this happen?
210210

211-
A number is stored in memory in its binary form, a sequence of ones and zeroes. But fractions like `0.1`, `0.2` that look simple in the decimal numeric system are actually unending fractions in their binary form.
211+
A number is stored in memory in its binary form, a sequence of bits - ones and zeroes. But fractions like `0.1`, `0.2` that look simple in the decimal numeric system are actually unending fractions in their binary form.
212212

213213
In other words, what is `0.1`? It is one divided by ten `1/10`, one-tenth. In decimal numeral system such numbers are easily representable. Compare it to one-third: `1/3`. It becomes an endless fraction `0.33333(3)`.
214214

215215
So, division by powers `10` is guaranteed to work well in the decimal system, but division by `3` is not. For the same reason, in the binary numeral system, the division by powers of `2` is guaranteed to work, but `1/10` becomes an endless binary fraction.
216216

217217
There's just no way to store *exactly 0.1* or *exactly 0.2* using the binary system, just like there is no way to store one-third as a decimal fraction.
218218

219-
The numeric format IEEE-754 solves this by rounding to the nearest possible number. These rounding rules normally don't allow us to see that "tiny precision loss", so the number shows up as `0.3`. But beware, the loss still exists.
219+
The numeric format IEEE-754 solves this by rounding to the nearest possible number. These rounding rules normally don't allow us to see that "tiny precision loss", but it exists.
220220

221221
We can see this in action:
222222
```js run
@@ -327,7 +327,7 @@ Please note that an empty or a space-only string is treated as `0` in all numeri
327327
There is a special built-in method [`Object.is`](mdn:js/Object/is) that compares values like `===`, but is more reliable for two edge cases:
328328

329329
1. It works with `NaN`: `Object.is(NaN, NaN) === true`, that's a good thing.
330-
2. Values `0` and `-0` are different: `Object.is(0, -0) === false`, it rarely matters, but these values technically are different.
330+
2. Values `0` and `-0` are different: `Object.is(0, -0) === false`, technically that's true, because internally the number has a sign bit that may be different even if all other bits are zeroes.
331331

332332
In all other cases, `Object.is(a, b)` is the same as `a === b`.
333333

1-js/05-data-types/06-iterable/article.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33

44
*Iterable* objects are a generalization of arrays. That's a concept that allows us to make any object useable in a `for..of` loop.
55

6-
Of course, Arrays are iterable. But there are many other built-in objects, that are iterable as well. For instance, Strings are iterable also. As we'll see, many built-in operators and methods rely on them.
6+
Of course, Arrays are iterable. But there are many other built-in objects, that are iterable as well. For instance, strings are also iterable.
77

8-
If an object represents a collection (list, set) of something, then `for..of` is a great syntax to loop over it, so let's see how to make it work.
8+
If an object isn't technically an array, but represents a collection (list, set) of something, then `for..of` is a great syntax to loop over it, so let's see how to make it work.
99

1010

1111
## Symbol.iterator
@@ -31,9 +31,9 @@ To make the `range` object iterable (and thus let `for..of` work) we need to add
3131
1. When `for..of` starts, it calls that method once (or errors if not found). The method must return an *iterator* -- an object with the method `next`.
3232
2. Onward, `for..of` works *only with that returned object*.
3333
3. When `for..of` wants the next value, it calls `next()` on that object.
34-
4. The result of `next()` must have the form `{done: Boolean, value: any}`, where `done=true` means that the iteration is finished, otherwise `value` must be the new value.
34+
4. The result of `next()` must have the form `{done: Boolean, value: any}`, where `done=true` means that the iteration is finished, otherwise `value` is the next value.
3535

36-
Here's the full implementation for `range`:
36+
Here's the full implementation for `range` with remarks:
3737

3838
```js run
3939
let range = {
@@ -68,10 +68,10 @@ for (let num of range) {
6868
}
6969
```
7070

71-
Please note the core feature of iterables: an important separation of concerns:
71+
Please note the core feature of iterables: separation of concerns.
7272

7373
- The `range` itself does not have the `next()` method.
74-
- Instead, another object, a so-called "iterator" is created by the call to `range[Symbol.iterator]()`, and it handles the whole iteration.
74+
- Instead, another object, a so-called "iterator" is created by the call to `range[Symbol.iterator]()`, and its `next()` generates values for the iteration.
7575

7676
So, the iterator object is separate from the object it iterates over.
7777

@@ -105,7 +105,7 @@ for (let num of range) {
105105

106106
Now `range[Symbol.iterator]()` returns the `range` object itself: it has the necessary `next()` method and remembers the current iteration progress in `this.current`. Shorter? Yes. And sometimes that's fine too.
107107

108-
The downside is that now it's impossible to have two `for..of` loops running over the object simultaneously: they'll share the iteration state, because there's only one iterator -- the object itself. But two parallel for-ofs is a rare thing, doable with some async scenarios.
108+
The downside is that now it's impossible to have two `for..of` loops running over the object simultaneously: they'll share the iteration state, because there's only one iterator -- the object itself. But two parallel for-ofs is a rare thing, even in async scenarios.
109109

110110
```smart header="Infinite iterators"
111111
Infinite iterators are also possible. For instance, the `range` becomes infinite for `range.to = Infinity`. Or we can make an iterable object that generates an infinite sequence of pseudorandom numbers. Also can be useful.
@@ -193,11 +193,11 @@ for (let item of arrayLike) {}
193193
*/!*
194194
```
195195

196-
What do they have in common? Both iterables and array-likes are usually *not arrays*, they don't have `push`, `pop` etc. That's rather inconvenient if we have such an object and want to work with it as with an array.
196+
Both iterables and array-likes are usually *not arrays*, they don't have `push`, `pop` etc. That's rather inconvenient if we have such an object and want to work with it as with an array. E.g. we would like to work with `range` using array methods. How to achieve that?
197197

198198
## Array.from
199199

200-
There's a universal method [Array.from](mdn:js/Array/from) that brings them together. It takes an iterable or array-like value and makes a "real" `Array` from it. Then we can call array methods on it.
200+
There's a universal method [Array.from](mdn:js/Array/from) that takes an iterable or array-like value and makes a "real" `Array` from it. Then we can call array methods on it.
201201

202202
For instance:
203203

@@ -283,7 +283,7 @@ let str = '𝒳😂𩷶';
283283

284284
alert( slice(str, 1, 3) ); // 😂𩷶
285285

286-
// native method does not support surrogate pairs
286+
// the native method does not support surrogate pairs
287287
alert( str.slice(1, 3) ); // garbage (two pieces from different surrogate pairs)
288288
```
289289

1-js/06-advanced-functions/04-var/article.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,6 @@ alert(test); // true, the variable lives after if
4242
*/!*
4343
```
4444

45-
<<<<<<< HEAD
46-
If we used `let test` on the 2nd line, then it wouldn't be visible to `alert`. But `var` ignores code blocks, so we've got a global `test`.
47-
=======
4845
As `var` ignores code blocks, we've got a global variable `test`.
4946

5047
If we used `let test` instead of `var test`, then the variable would only be visible inside `if`:
@@ -58,7 +55,6 @@ if (true) {
5855
alert(test); // ReferenceError: test is not defined
5956
*/!*
6057
```
61-
>>>>>>> 039716de8a96f49b5fccd7aed5effff2e719dfe5
6258

6359
The same thing for loops: `var` cannot be block- or loop-local:
6460

Lines changed: 15 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
# Microtasks and event loop
2+
# Microtasks
33

44
Promise handlers `.then`/`.catch`/`.finally` are always asynchronous.
55

@@ -10,18 +10,18 @@ Here's a demo:
1010
```js run
1111
let promise = Promise.resolve();
1212

13-
promise.then(() => alert("promise done"));
13+
promise.then(() => alert("promise done!"));
1414

1515
alert("code finished"); // this alert shows first
1616
```
1717

18-
If you run it, you see `code finished` first, and then `promise done`.
18+
If you run it, you see `code finished` first, and then `promise done!`.
1919

2020
That's strange, because the promise is definitely done from the beginning.
2121

2222
Why did the `.then` trigger afterwards? What's going on?
2323

24-
# Microtasks
24+
## Microtasks queue
2525

2626
Asynchronous tasks need proper management. For that, the ECMA standard specifies an internal queue `PromiseJobs`, more often referred to as the "microtask queue" (V8 term).
2727

@@ -52,77 +52,6 @@ Promise.resolve()
5252

5353
Now the order is as intended.
5454

55-
## Event loop
56-
57-
In-browser JavaScript, as well as Node.js, is based on an *event loop*.
58-
59-
"Event loop" is a process when the engine sleeps and waits for events, then reacts on those and sleeps again.
60-
61-
Examples of events:
62-
- `mousemove`, a user moved their mouse.
63-
- `setTimeout` handler is to be called.
64-
- an external `<script src="...">` is loaded, ready to be executed.
65-
- a network operation, e.g. `fetch` is complete.
66-
- ...etc.
67-
68-
Things happen -- the engine handles them -- and waits for more to happen (while sleeping and consuming close to zero CPU).
69-
70-
![](eventLoop.svg)
71-
72-
As you can see, there's also a queue here. A so-called "macrotask queue" (v8 term).
73-
74-
When an event happens, while the engine is busy, its handling is enqueued.
75-
76-
For instance, while the engine is busy processing a network `fetch`, a user may move their mouse causing `mousemove`, and `setTimeout` may be due and so on, just as painted on the picture above.
77-
78-
Events from the macrotask queue are processed on "first come – first served" basis. When the engine browser finishes with `fetch`, it handles `mousemove` event, then `setTimeout` handler, and so on.
79-
80-
So far, quite simple, right? The engine is busy, so other tasks queue up.
81-
82-
Now the important stuff.
83-
84-
**Microtask queue has a higher priority than the macrotask queue.**
85-
86-
In other words, the engine first executes all microtasks, and then takes a macrotask. Promise handling always has the priority.
87-
88-
For instance, take a look:
89-
90-
```js run
91-
setTimeout(() => alert("timeout"));
92-
93-
Promise.resolve()
94-
.then(() => alert("promise"));
95-
96-
alert("code");
97-
```
98-
99-
What's the order?
100-
101-
1. `code` shows first, because it's a regular synchronous call.
102-
2. `promise` shows second, because `.then` passes through the microtask queue, and runs after the current code.
103-
3. `timeout` shows last, because it's a macrotask.
104-
105-
It may happen that while handling a macrotask, new promises are created.
106-
107-
Or, vice-versa, a microtask schedules a macrotask (e.g. `setTimeout`).
108-
109-
For instance, here `.then` schedules a `setTimeout`:
110-
111-
```js run
112-
Promise.resolve()
113-
.then(() => {
114-
setTimeout(() => alert("timeout"), 0);
115-
})
116-
.then(() => {
117-
alert("promise");
118-
});
119-
```
120-
121-
Naturally, `promise` shows up first, because `setTimeout` macrotask awaits in the less-priority macrotask queue.
122-
123-
As a logical consequence, macrotasks are handled only when promises give the engine a "free time". So if we have a promise chain that doesn't wait for anything, then things like `setTimeout` or event handlers can never get in the middle.
124-
125-
12655
## Unhandled rejection
12756

12857
Remember the `unhandledrejection` event from the article <info:promise-error-handling>?
@@ -131,34 +60,33 @@ Now we can see exactly how JavaScript finds out that there was an unhandled reje
13160

13261
**An "unhandled rejection" occurs when a promise error is not handled at the end of the microtask queue.**
13362

134-
For instance, consider this code:
63+
Normally, if we expect an error, we add `.catch` to the promise chain to handle it:
13564

13665
```js run
13766
let promise = Promise.reject(new Error("Promise Failed!"));
67+
*!*
68+
promise.catch(err => alert('caught'));
69+
*/!*
13870

139-
window.addEventListener('unhandledrejection', event => {
140-
alert(event.reason); // Promise Failed!
141-
});
71+
// doesn't run: error handled
72+
window.addEventListener('unhandledrejection', event => alert(event.reason));
14273
```
14374

14475
But if we forget to add `.catch`, then, after the microtask queue is empty, the engine triggers the event:
14576

14677
```js run
14778
let promise = Promise.reject(new Error("Promise Failed!"));
148-
*!*
149-
promise.catch(err => alert('caught'));
150-
*/!*
15179

152-
// no error, all quiet
80+
// Promise Failed!
15381
window.addEventListener('unhandledrejection', event => alert(event.reason));
15482
```
15583

156-
Now let's say, we'll be catching the error, but after `setTimeout`:
84+
What if we handle the error later? Like this:
15785

15886
```js run
15987
let promise = Promise.reject(new Error("Promise Failed!"));
16088
*!*
161-
setTimeout(() => promise.catch(err => alert('caught')));
89+
setTimeout(() => promise.catch(err => alert('caught')), 1000);
16290
*/!*
16391

16492
// Error: Promise Failed!
@@ -173,16 +101,12 @@ But now we understand that `unhandledrejection` is generated when the microtask
173101

174102
In the example above, `.catch` added by `setTimeout` also triggers. But it does so later, after `unhandledrejection` has already occurred, so it doesn't change anything.
175103

176-
**So, `.then/catch/finally` are called after the current code is finished.**
177-
178-
If we need to guarantee that a piece of code is executed after `.then/catch/finally`, it's best to add it into a chained `.then` call.
179-
180-
- There's also a "macrotask queue" that keeps various events, network operation results, `setTimeout`-scheduled calls, and so on. These are also called "macrotasks" (v8 term).
104+
## Summary
181105

182106
Promise handling is always asynchronous, as all promise actions pass through the internal "promise jobs" queue, also called "microtask queue" (V8 term).
183107

184108
So `.then/catch/finally` handlers are always called after the current code is finished.
185109

186-
In other words, they have lower priority.
110+
If we need to guarantee that a piece of code is executed after `.then/catch/finally`, we can add it into a chained `.then` call.
187111

188112
In most Javascript engines, including browsers and Node.js, the concept of microtasks is closely tied with the "event loop" and "macrotasks". As these have no direct relation to promises, they are covered in another part of the tutorial, in the article <info:event-loop>.

2-ui/1-document/04-searching-elements-dom/article.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ Also, there's a global variable named by `id` that references the element:
5050
<script>
5151
let elem = 5; // now elem is 5, not a reference to <div id="elem">
5252
53-
alert(elem); // the variable overrides the element
53+
alert(elem); // 5
5454
</script>
5555
```
5656

@@ -110,7 +110,7 @@ Pseudo-classes in the CSS selector like `:hover` and `:active` are also supporte
110110

111111
The call to `elem.querySelector(css)` returns the first element for the given CSS selector.
112112

113-
In other words, the result is the same as `elem.querySelectorAll(css)[0]`, but the latter is looking for *all* elements and picking one, while `elem.querySelector` just looks for one. So it's faster and shorter to write.
113+
In other words, the result is the same as `elem.querySelectorAll(css)[0]`, but the latter is looking for *all* elements and picking one, while `elem.querySelector` just looks for one. So it's faster and also shorter to write.
114114

115115
## matches
116116

@@ -310,8 +310,6 @@ If we use it instead, then both scripts output `1`:
310310
311311
Now we can easily see the difference. The static collection did not increase after the appearance of a new `div` in the document.
312312
313-
Here we used separate scripts to illustrate how the element addition affects the collection, but any DOM manipulations affect them. Soon we'll see more of them.
314-
315313
## Summary
316314
317315
There are 6 main methods to search for nodes in DOM:
@@ -372,5 +370,5 @@ Besides that:
372370
- There is `elem.matches(css)` to check if `elem` matches the given CSS selector.
373371
- There is `elem.closest(css)` to look for the nearest ancestor that matches the given CSS-selector. The `elem` itself is also checked.
374372
375-
And let's mention one more method here to check for the child-parent relationship:
373+
And let's mention one more method here to check for the child-parent relationship, as it's sometimes useful:
376374
- `elemA.contains(elemB)` returns true if `elemB` is inside `elemA` (a descendant of `elemA`) or when `elemA==elemB`.

0 commit comments

Comments
 (0)