(253-1)
(che equivale a `9007199254740991`), o minori di -(253-1)
. Questa è una limitazione tecnica dovuta alla loro rappresentazione interna.
Per la maggior parte degli scopi, questo intervallo è sufficiente, ma in alcuni casi potremmo aver bisogno di numeri molto grandi, ad esempio per la crittografia o timestamp con precisione al microsecondo.
+=======
+In JavaScript, the "number" type cannot safely represent integer values larger than (253-1)
(that's `9007199254740991`), or less than -(253-1)
for negatives.
+
+To be really precise, the "number" type can store larger integers (up to 1.7976931348623157 * 10308
), but outside of the safe integer range ±(253-1)
there'll be a precision error, because not all digits fit into the fixed 64-bit storage. So an "approximate" value may be stored.
+
+For example, these two numbers (right above the safe range) are the same:
+
+```js
+console.log(9007199254740991 + 1); // 9007199254740992
+console.log(9007199254740991 + 2); // 9007199254740992
+```
+
+So to say, all odd integers greater than (253-1)
can't be stored at all in the "number" type.
+
+For most purposes ±(253-1)
range is quite enough, but sometimes we need the entire range of really big integers, e.g. for cryptography or microsecond-precision timestamps.
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
Il tipo `BigInt` è stato aggiunto di recente al linguaggio, e consente di rappresentare numeri interi di lunghezza arbitraria.
@@ -81,6 +108,7 @@ const bigInt = 1234567890123456789012345678901234567890n;
Poiché i `BigInt` sono utilizzati raramente, non li analizzeremo in questo articolo, ma li vedremo più in dettaglio nel capitolo dedicato ±(253-1)
.
+ - `bigint` for integer numbers of arbitrary length.
+ - `string` for strings. A string may have zero or more characters, there's no separate single-character type.
+ - `boolean` for `true`/`false`.
+ - `null` for unknown values -- a standalone type that has a single value `null`.
+ - `undefined` for unassigned values -- a standalone type that has a single value `undefined`.
+ - `symbol` for unique identifiers.
+- And one non-primitive data type:
+ - `object` for more complex data structures.
+
+The `typeof` operator allows us to see which type is stored in a variable.
+
+- Usually used as `typeof x`, but `typeof(x)` is also possible.
+- Returns a string with the name of the type, like `"string"`.
+- For `null` returns `"object"` -- this is an error in the language, it's not actually an object.
+
+In the next chapters, we'll concentrate on primitive values and once we're familiar with them, we'll move on to objects.
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
diff --git a/1-js/02-first-steps/07-type-conversions/article.md b/1-js/02-first-steps/07-type-conversions/article.md
index df98466c0..e5ffbc3ab 100644
--- a/1-js/02-first-steps/07-type-conversions/article.md
+++ b/1-js/02-first-steps/07-type-conversions/article.md
@@ -6,8 +6,15 @@ Ad esempio, `alert` converte automaticamente un valore qualsiasi in una stringa,
Ci sono invece casi in cui è necessario convertire esplicitamente i valori per poter evitare errori.
+<<<<<<< HEAD
```smart header="Non parliamo ancora di oggetti"
In questo capitolo non parleremo ancora di oggetti ma ci dedicheremo ai tipi primitivi. Approfondiremo gli oggetti e la loro conversione dopo averli studiati, nel capitolo true e false
| `1` e `0` |
| `string` | Gli spazi bianchi all'inizio e alla fine vengono rimossi. Se la stringa rimanente è vuota, il risultato sarà `0`. Altrimenti, il numero viene "letto" dalla stringa. Un errore restituirà `NaN`. |
+=======
+|true and false
| `1` and `0` |
+| `string` | Whitespaces (includes spaces, tabs `\t`, newlines `\n` etc.) from the start and end are removed. If the remaining string is empty, the result is `0`. Otherwise, the number is "read" from the string. An error gives `NaN`. |
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
Esempi:
@@ -140,7 +156,11 @@ La conversione segue le seguenti regole:
|`undefined`|`NaN`|
|`null`|`0`|
|true / false
| `1 / 0` |
+<<<<<<< HEAD
| `string` | La stringa viene letta per "com'è", gli spazi bianchi agli estremi vengono ignorati. Una stringa vuota diventa `0`. Un errore restituisce `NaN`. |
+=======
+| `string` | The string is read "as is", whitespaces (includes spaces, tabs `\t`, newlines `\n` etc.) from both sides are ignored. An empty string becomes `0`. An error gives `NaN`. |
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
**`Conversione booleana`** -- Avviene nelle operazioni logiche, può anche essere richiamato esplicitamente con `Boolean(value)`.
diff --git a/1-js/02-first-steps/08-operators/3-primitive-conversions-questions/solution.md b/1-js/02-first-steps/08-operators/3-primitive-conversions-questions/solution.md
index 43ac15a17..36498e242 100644
--- a/1-js/02-first-steps/08-operators/3-primitive-conversions-questions/solution.md
+++ b/1-js/02-first-steps/08-operators/3-primitive-conversions-questions/solution.md
@@ -16,6 +16,7 @@ undefined + 1 = NaN // (6)
" \t \n" - 2 = -2 // (7)
```
+<<<<<<< HEAD
1. L'addizione con una stringa `"" + 1` converte `1` a stringa: `"" + 1 = "1"`, applichiamo la stessa regola a `"1" + 0`.
2. La sottrazione `-` (come molte altre operazioni matematiche) funziona solamente con i numeri, quindi una stringa vuota come: `""` viene convertita in `0`.
3. La somma con una stringa appende in coda alla stringa il numero `5`.
@@ -23,3 +24,12 @@ undefined + 1 = NaN // (6)
5. `null` diventa `0` dopo la conversione numerica.
6. `undefined` diventa `NaN` dopo la conversione numerica.
7. Gli spazi all'inizio e alla fine di una stringa vengono rimossi quando questa viene convertita ad numero. In questo caso l'intera stringa è composta da spazi, come `\t`, `\n` ed uno "spazio" normale tra di essi. Quindi allo stesso modo di una stringa vuota, diventa `0`.
+=======
+1. The addition with a string `"" + 1` converts `1` to a string: `"" + 1 = "1"`, and then we have `"1" + 0`, the same rule is applied.
+2. The subtraction `-` (like most math operations) only works with numbers, it converts an empty string `""` to `0`.
+3. The addition with a string appends the number `5` to the string.
+4. The subtraction always converts to numbers, so it makes `" -9 "` a number `-9` (ignoring spaces around it).
+5. `null` becomes `0` after the numeric conversion.
+6. `undefined` becomes `NaN` after the numeric conversion.
+7. Space characters are trimmed off string start and end when a string is converted to a number. Here the whole string consists of space characters, such as `\t`, `\n` and a "regular" space between them. So, similarly to an empty string, it becomes `0`.
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
diff --git a/1-js/02-first-steps/08-operators/article.md b/1-js/02-first-steps/08-operators/article.md
index cc772d4c8..8cd203d92 100644
--- a/1-js/02-first-steps/08-operators/article.md
+++ b/1-js/02-first-steps/08-operators/article.md
@@ -51,8 +51,14 @@ Il risultato di `a % b` è il [resto](https://en.wikipedia.org/wiki/Remainder) d
Ad esempio:
```js run
+<<<<<<< HEAD
alert( 5 % 2 ); // 1, è il resto dell'operazione 5 diviso 2
alert( 8 % 3 ); // 2, è il resto dell'operazione 8 diviso 3
+=======
+alert( 5 % 2 ); // 1, the remainder of 5 divided by 2
+alert( 8 % 3 ); // 2, the remainder of 8 divided by 3
+alert( 8 % 4 ); // 0, the remainder of 8 divided by 4
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
```
### Elevamento a Potenza **
@@ -70,7 +76,11 @@ alert( 2 ** 3 ); // 2³ = 8
alert( 2 ** 4 ); // 2⁴ = 16
```
+<<<<<<< HEAD
Come in matematica, l'esponente può essere anche un valore numerico non intero.
+=======
+Just like in maths, the exponentiation operator is defined for non-integer numbers as well.
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
Ad esempio, la radice quadrata può essere vista come un elevamento a potenza con esponente `1/2`:
@@ -82,7 +92,11 @@ alert( 8 ** (1/3) ); // 2 (potenza 1/3 equivale alla radice cubica)
## Concatenazione di stringhe, operatore binario +
+<<<<<<< HEAD
Adesso diamo un'occhiata alle caratteristiche degli operatori in JavaScript, che vanno oltre l'aritmetica scolastica.
+=======
+Let's meet the features of JavaScript operators that are beyond school arithmetics.
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
Solitamente l'operatore di somma `+` viene utilizzato per sommare due numeri.
@@ -199,22 +213,30 @@ Un estratto della [tabella delle precedenze](https://developer.mozilla.org/en/Ja
| Precedence | Name | Sign |
|------------|------|------|
| ... | ... | ... |
-| 17 | unary plus | `+` |
-| 17 | unary negation | `-` |
-| 16 | exponentiation | `**` |
-| 15 | multiplication | `*` |
-| 15 | division | `/` |
-| 13 | addition | `+` |
-| 13 | subtraction | `-` |
+| 14 | unary plus | `+` |
+| 14 | unary negation | `-` |
+| 13 | exponentiation | `**` |
+| 12 | multiplication | `*` |
+| 12 | division | `/` |
+| 11 | addition | `+` |
+| 11 | subtraction | `-` |
| ... | ... | ... |
-| 3 | assignment | `=` |
+| 2 | assignment | `=` |
| ... | ... | ... |
+<<<<<<< HEAD
Come possiamo vedere, la "somma unaria"(unary plus) ha una priorità di `17`, che è maggiore del `13` dell'addizione(`+` binario). Questo è il motivo per cui l'espressione `"+apples + +oranges"` esegue prima il `+` unario, e successivamente l'addizione.
+=======
+As we can see, the "unary plus" has a priority of `14` which is higher than the `11` of "addition" (binary plus). That's why, in the expression `"+apples + +oranges"`, unary pluses work before the addition.
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
## Assegnazione
+<<<<<<< HEAD
Da notare che anche l'assegnazione `=` è un operatore. Viene infatti elencato nella tabella delle precedenze con una priorità molto bassa: `3`.
+=======
+Let's note that an assignment `=` is also an operator. It is listed in the precedence table with the very low priority of `2`.
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
Questo è il motivo per cui quando assegniamo un valore ad una variabile, come `x = 2 * 2 + 1`, i calcoli vengono eseguiti per primi, e successivamente viene valutato l'operatore `=`, che memorizza il risultato in `x`.
@@ -312,9 +334,14 @@ Questi operatori hanno la stessa precedenza delle normali assegnazioni, quindi v
```js run
let n = 2;
-n *= 3 + 5;
+n *= 3 + 5; // right part evaluated first, same as n *= 8
+<<<<<<< HEAD
alert( n ); // 16 (prima viene valutata la parte destra, equivale a n *= 8)
+=======
+alert( n ); // 16
+```
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
## Incremento/Decremento
@@ -445,7 +472,11 @@ La lista degli operatori:
- RIGHT SHIFT ( `>>` )
- ZERO-FILL RIGHT SHIFT ( `>>>` )
+<<<<<<< HEAD
Questi operatori vengono utilizzati molto raramente, quando abbiamo bisogno di lavorare con i numeri al più basso livello (bit per bit). Non avremo bisogno di questi operatori molto presto, poiché lo sviluppo web ne fa un uso limitato, ma in alcune aree speciali, come la crittografia, sono utili.In caso di necessità potete leggere l'articolo [operatori BitWise](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators) su MDN.
+=======
+These operators are used very rarely, when we need to fiddle with numbers on the very lowest (bitwise) level. We won't need these operators any time soon, as web development has little use of them, but in some special areas, such as cryptography, they are useful. You can read the [Bitwise Operators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#bitwise_operators) chapter on MDN when a need arises.
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
## Virgola
diff --git a/1-js/02-first-steps/10-ifelse/article.md b/1-js/02-first-steps/10-ifelse/article.md
index dfceb67e8..8062869e1 100644
--- a/1-js/02-first-steps/10-ifelse/article.md
+++ b/1-js/02-first-steps/10-ifelse/article.md
@@ -68,7 +68,11 @@ if (cond) {
## La clausola "else"
+<<<<<<< HEAD
L'istruzione `if` può essere seguita da un blocco opzionale "else". Questo viene eseguito quando la condizione è falsa.
+=======
+The `if` statement may contain an optional `else` block. It executes when the condition is falsy.
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
Ad esempio:
```js run
@@ -180,10 +184,17 @@ alert( message );
Potrebbe essere difficile, inizialmente, capirne la logica. Ma dopo averlo guardato da più vicino ci accorgeremo che è una semplice sequenza di condizioni.
+<<<<<<< HEAD
1. Il primo operatore "?" controlla `age < 3`.
2. Se è vero -- ritorna `'Hi, baby!'`, altrimenti -- segue la colonna `":"`, controlla `age < 18`.
3. Se questo è vero -- ritorna `'Hello!'`, altrimenti -- segue la colonna `":"`, controlla `age < 100`.
4. Se questo è vero -- ritorna `'Greetings!'`, altrimenti -- segue la colonna `":"`, ritorna `'What an unusual age!'`.
+=======
+1. The first question mark checks whether `age < 3`.
+2. If true -- it returns `'Hi, baby!'`. Otherwise, it continues to the expression after the colon ":", checking `age < 18`.
+3. If that's true -- it returns `'Hello!'`. Otherwise, it continues to the expression after the next colon ":", checking `age < 100`.
+4. If that's true -- it returns `'Greetings!'`. Otherwise, it continues to the expression after the last colon ":", returning `'What an unusual age!'`.
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
La stessa logica riscritta utilizzando `if..else`:
diff --git a/1-js/02-first-steps/11-logical-operators/3-alert-1-null-2/solution.md b/1-js/02-first-steps/11-logical-operators/3-alert-1-null-2/solution.md
index aadc5b0bd..cc1e6030f 100644
--- a/1-js/02-first-steps/11-logical-operators/3-alert-1-null-2/solution.md
+++ b/1-js/02-first-steps/11-logical-operators/3-alert-1-null-2/solution.md
@@ -1,6 +1,6 @@
La risposta è: `null`, perchè è il primo valore falso nella lista.
```js run
-alert( 1 && null && 2 );
+alert(1 && null && 2);
```
diff --git a/1-js/02-first-steps/12-nullish-coalescing-operator/article.md b/1-js/02-first-steps/12-nullish-coalescing-operator/article.md
index 4c60535d7..f6b05d4f3 100644
--- a/1-js/02-first-steps/12-nullish-coalescing-operator/article.md
+++ b/1-js/02-first-steps/12-nullish-coalescing-operator/article.md
@@ -4,7 +4,11 @@
Il *nullish coalescing operator* è rappresentato da due punti di domanda `??`.
+<<<<<<< HEAD
Siccome trattiamo `null` e `undefined` in modo simile, avremo bisogno di una definizione particolare. In questo articolo, diremo che un'espressione è "definita" quando non è né `null` né `undefined`.
+=======
+As it treats `null` and `undefined` similarly, we'll use a special term here, in this article. For brevity, we'll say that a value is "defined" when it's neither `null` nor `undefined`.
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
Il risultato di `a ?? b` è:
- se `a` è definito, allora `a`,
@@ -22,12 +26,18 @@ result = (a !== null && a !== undefined) ? a : b;
Un caso d'uso comune per l'operatore `??` è quello di fornire un valore di default per una variabile potenzialmente "non definita".
+<<<<<<< HEAD
Per esempio, qui mostriamo `Anonymous` se `user` non è definito:
+=======
+The common use case for `??` is to provide a default value.
+
+For example, here we show `user` if its value isn't `null/undefined`, otherwise `Anonymous`:
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
```js run
let user;
-alert(user ?? "Anonymous"); // Anonymous (user not defined)
+alert(user ?? "Anonymous"); // Anonymous (user is undefined)
```
Ovviamente, se `user` ha un qualsiasi valore eccetto `null/undefined`, allora vedremo quel valore:
@@ -35,14 +45,20 @@ Ovviamente, se `user` ha un qualsiasi valore eccetto `null/undefined`, allora ve
```js run
let user = "John";
-alert(user ?? "Anonymous"); // John (user defined)
+alert(user ?? "Anonymous"); // John (user is not null/undefined)
```
Possiamo anche usare una sequenza di `??` per selezionare, da una lista, il primo valore che non sia `null/undefined`.
+<<<<<<< HEAD
Per esempio, supponiamo di avere i dati di un utente nelle variabili `firstName`, `lastName` o `nickName`. Tutte queste potrebbero essere non definite, se l'utente dovesse decidere di non inserirne i valori.
Vorremmo visualizzare il nome dell'utente usando una di queste variabili, oppure mostrare "Anonymous" se nessuna di esse è definita.
+=======
+Let's say we have a user's data in variables `firstName`, `lastName` or `nickName`. All of them may be not defined, if the user decided not to fill in the corresponding values.
+
+We'd like to display the user name using one of these variables, or show "Anonymous" if all of them are `null/undefined`.
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
Usiamo l'operatore `??`:
@@ -74,7 +90,11 @@ alert(firstName || lastName || nickName || "Anonymous"); // Supercoder
*/!*
```
+<<<<<<< HEAD
L'operatore OR `||` esiste sin dagli inizi di JavaScript e gli sviluppatori lo hanno usato a tale scopo per molto tempo.
+=======
+Historically, the OR `||` operator was there first. It's been there since the beginning of JavaScript, so developers were using it for such purposes for a long time.
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
Il nullish coalescing operator `??`, invece, è stato aggiunto recentemente. La ragione è che alcuni sviluppatori non erano del tutto contenti dell'operatore `||`.
@@ -104,9 +124,17 @@ Se un'altezza pari a zero è un valore accettabile, questo non dovrebbe essere r
## Precedenza
+<<<<<<< HEAD
La precedenza dell'operatore `??` è piuttosto bassa: `5` nella [MDN table](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table). Quindi `??` è valutato prima di `=` e `?`, ma dopo la maggior parte degli altri operatori, come `+` o `*`.
Quindi, se volessimo scegliere un valore tramite l'operatore `??` in un'espressione contenente altri operatori, dovremmo considerare l'utilizzo delle parentesi:
+=======
+The precedence of the `??` operator is the same as `||`. They both equal `3` in the [MDN table](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table).
+
+That means that, just like `||`, the nullish coalescing operator `??` is evaluated before `=` and `?`, but after most other operations, such as `+`, `*`.
+
+So we may need to add parentheses in expressions like this:
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
```js run
let height = null;
@@ -124,7 +152,11 @@ Altrimenti, se omettessimo le parentesi, siccome `*` ha una precedenza maggiore
// senza parentesi
let area = height ?? 100 * width ?? 50;
+<<<<<<< HEAD
// ...funziona allo stesso modo del seguente codice (probabilmente non ciò che vogliamo)
+=======
+// ...works this way (not what we want):
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
let area = height ?? (100 * width) ?? 50;
```
diff --git a/1-js/02-first-steps/13-while-for/article.md b/1-js/02-first-steps/13-while-for/article.md
index 81f44c398..6cf521b78 100644
--- a/1-js/02-first-steps/13-while-for/article.md
+++ b/1-js/02-first-steps/13-while-for/article.md
@@ -6,7 +6,24 @@ Ad esempio, quando abbiamo bisogno di ritornare, una dopo l'altra, della merce d
I *cicli* sono un modo di ripetere una stessa parte di codice più volte.
+<<<<<<< HEAD
## Il ciclo "while"
+=======
+```smart header="The for..of and for..in loops"
+A small announcement for advanced readers.
+
+This article covers only basic loops: `while`, `do..while` and `for(..;..;..)`.
+
+If you came to this article searching for other types of loops, here are the pointers:
+
+- See [for..in](info:object#forin) to loop over object properties.
+- See [for..of](info:array#loops) and [iterables](info:iterable) for looping over arrays and iterable objects.
+
+Otherwise, please read on.
+```
+
+## The "while" loop
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
Il ciclo `while` ha la seguente sintassi:
@@ -161,11 +178,14 @@ for (i = 0; i < 3; i++) { // utilizza una variabile esistente
alert(i); // 3; la variabile `i` è accessibile (è stata dichiarata fuori dal corpo del ciclo)
```
-
````
+<<<<<<< HEAD
### Parti opzionali
+=======
+### Skipping parts
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
Ogni parte del ciclo `for` è opzionale.
@@ -265,7 +285,13 @@ for (let i = 0; i < 10; i++) {
}
```
+<<<<<<< HEAD
Ovviamente possiamo raccogliere il codice in un blocco `if` piuttosto di usare `continue`. Dal punto di vista tecnico l'esempio sopra è identico a quello che lo precede, che invece utilizza `continue`. Nell'esempio sopra il codice dentro il corpo di `if` è una semplice chiamata ad `alert`; ma se il codice fosse più lungo di un paio di righe si rischierebbe di perdere in leggibilità.
+=======
+From a technical point of view, this is identical to the example above. Surely, we can just wrap the code in an `if` block instead of using `continue`.
+
+But as a side effect, this created one more level of nesting (the `alert` call inside the curly braces). If the code inside of `if` is longer than a few lines, that may decrease the overall readability.
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
````
````warn header="Vietato `break/continue` alla desta di '?'"
@@ -283,7 +309,6 @@ if (i > 5) {
...E lo riscriviamo utilizzando l'operatore ternario:
-
```js no-beautify
(i > 5) ? alert(i) : *!*continue*/!*; // continue non è consentito qui
```
@@ -320,7 +345,12 @@ Abbiamo bisogno di un modo per bloccare il processo se l'utente annulla l'input.
Un semplice `break` dopo la variabile `input` interromperebbe solo il ciclo più interno. Questo non è sufficiente. I *label* ci vengono in soccorso.
+<<<<<<< HEAD
Un *label* ("etichetta") è un identificatore seguito da ":" e da un ciclo:
+=======
+A *label* is an identifier with a colon before a loop:
+
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
```js
labelName: for (...) {
...
@@ -344,6 +374,7 @@ Come nell'esempio:
// fa qualcosa con i valori...
}
}
+
alert('Done!');
```
@@ -363,14 +394,24 @@ Anche la direttiva `continue` può essere utilizzata con un'etichetta. In questo
````warn header="I *label* non equivalgono a \"goto\""
I *label* non permettono di saltare in un punto arbitrario del codice.
+<<<<<<< HEAD
Ad esempio, non è possibile:
+=======
+For example, it is impossible to do this:
+
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
```js
break label; // non salta all'etichetta sotto
label: for (...)
```
+<<<<<<< HEAD
La direttiva `break` deve essere all'interno del blocco di codice. Tecnicamente l'etichettatura funzionerà con qualsiasi blocco di codice, ad esempio:
+=======
+A `break` directive must be inside a code block. Technically, any labelled code block will do, e.g.:
+
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
```js
label: {
// ...
diff --git a/1-js/02-first-steps/14-switch/article.md b/1-js/02-first-steps/14-switch/article.md
index 4bc607614..5e4b4fd56 100644
--- a/1-js/02-first-steps/14-switch/article.md
+++ b/1-js/02-first-steps/14-switch/article.md
@@ -140,7 +140,11 @@ switch (a) {
Ora sia `3` che `5` mostreranno lo stesso messaggio.
+<<<<<<< HEAD
L'abilità di "raggruppare" più `case` è un effetto collaterale di come `switch/case` funziona senza `break`. Qui l'esecuzione del `case 3` inizia dalla linea `(*)` e prosegue fino a `case 5`, perché non c'è alcun `break`.
+=======
+The ability to "group" cases is a side effect of how `switch/case` works without `break`. Here the execution of `case 3` starts from the line `(*)` and goes through `case 5`, because there's no `break`.
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
## Il tipo conta
diff --git a/1-js/02-first-steps/15-function-basics/1-if-else-required/solution.md b/1-js/02-first-steps/15-function-basics/1-if-else-required/solution.md
index 7fe85340a..07575fa30 100644
--- a/1-js/02-first-steps/15-function-basics/1-if-else-required/solution.md
+++ b/1-js/02-first-steps/15-function-basics/1-if-else-required/solution.md
@@ -1 +1,7 @@
-No, non ci sono differenze.
\ No newline at end of file
+<<<<<<< HEAD
+No, non ci sono differenze.
+=======
+No difference!
+
+In both cases, `return confirm('Did parents allow you?')` executes exactly when the `if` condition is falsy.
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
diff --git a/1-js/02-first-steps/15-function-basics/article.md b/1-js/02-first-steps/15-function-basics/article.md
index bc2dc7a94..1fb08f25b 100644
--- a/1-js/02-first-steps/15-function-basics/article.md
+++ b/1-js/02-first-steps/15-function-basics/article.md
@@ -24,7 +24,7 @@ La parola chiave `function` va posta all'inizio; viene seguita dal *nome della f
```js
function name(parameter1, parameter2, ... parameterN) {
- ...body...
+ // body
}
```
@@ -177,8 +177,13 @@ Quando un valore viene passato come parametro di funzione, vine anche chiamato *
In altre parole
In other words, per chiarire questi termini:
+<<<<<<< HEAD
- Un parametro è la variabile elencata tra parentesi nella dichiarazione della funzione (fa parte della dichiarazione).
- Un argomento è il valore passato alla funzione quando viene chiamata (fa parte della chiamata).
+=======
+- A parameter is the variable listed inside the parentheses in the function declaration (it's a declaration time term).
+- An argument is the value that is passed to the function when it is called (it's a call time term).
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
Dichiariamo le funzioni elencando i loro parametri, quindi le chiamiamo passando gli argomenti.
@@ -206,7 +211,17 @@ function showMessage(from, *!*text = "no text given"*/!*) {
showMessage("Ann"); // Ann: nessun text fornito
```
+<<<<<<< HEAD
Adesso, se il parametro `text` non viene passato, assumerà il valore `"no text given"`
+=======
+Now if the `text` parameter is not passed, it will get the value `"no text given"`.
+
+The default value also jumps in if the parameter exists, but strictly equals `undefined`, like this:
+
+```js
+showMessage("Ann", undefined); // Ann: no text given
+```
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
In questo caso `"no text given"` è una stringa, ma potrebbe essere un'espressione più complessa, che viene valutata e assegnata solamente se il parametro non viene fornito. Quindi, è possibile anche:
@@ -225,9 +240,49 @@ Nell'esempio sopra, `anotherFunctions()` non viene chiamata se viene passato il
Viene invece chiamata ogni volta che il parametro manca.
```
+<<<<<<< HEAD
A volte ha senso assegnare valori default ai parametri, non nella dichiarazione della funzione, ma in una fase successiva.
Possiamo verificare se il parametro viene passato durante l'esecuzione della funzione, confrontandolo con `undefined`:
+=======
+````smart header="Default parameters in old JavaScript code"
+Several years ago, JavaScript didn't support the syntax for default parameters. So people used other ways to specify them.
+
+Nowadays, we can come across them in old scripts.
+
+For example, an explicit check for `undefined`:
+
+```js
+function showMessage(from, text) {
+*!*
+ if (text === undefined) {
+ text = 'no text given';
+ }
+*/!*
+
+ alert( from + ": " + text );
+}
+```
+
+...Or using the `||` operator:
+
+```js
+function showMessage(from, text) {
+ // If the value of text is falsy, assign the default value
+ // this assumes that text == "" is the same as no text at all
+ text = text || 'no text given';
+ ...
+}
+```
+````
+
+
+### Alternative default parameters
+
+Sometimes it makes sense to assign default values for parameters at a later stage after the function declaration.
+
+We can check if the parameter is passed during the function execution, by comparing it with `undefined`:
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
```js run
function showMessage(text) {
@@ -409,7 +464,11 @@ Questi esempi assumono i significati comuni dei prefissi. Il loro significato di
```smart header="Nomi di funzioni ultra-corti"
Funzioni che vengono utilizzate *molto spesso* potrebbero avere nomi molto corti.
+<<<<<<< HEAD
Ad esempio il framework [jQuery](http://jquery.com) definisce una funzione con `$`. La libreria [Lodash](http://lodash.com/) ha nel *core* una funzione denominata `_`.
+=======
+For example, the [jQuery](https://jquery.com/) framework defines a function with `$`. The [Lodash](https://lodash.com/) library has its core function named `_`.
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
Queste sono eccezioni. Generalmente i nomi delle funzioni dovrebbero essere concisi e descrittivi.
```
@@ -477,7 +536,11 @@ function name(parameters, delimited, by, comma) {
Per rendere il codice pulito e più facile da leggere, è consigliabile utilizzare principalmente variabili locali e parametri di funzione, non variabili esterne.
+<<<<<<< HEAD
E' sempre più facile capire una funzione che accetta parametri, li lavora e ritorna un valore piuttosto di una funzione che non richiede parametri ma, come effetto collaterale, modifica variabili esterne.
+=======
+It is always easier to understand a function which gets parameters, works with them and returns a result than a function which gets no parameters, but modifies outer variables as a side effect.
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
Denominare le funzioni:
diff --git a/1-js/02-first-steps/16-function-expressions/article.md b/1-js/02-first-steps/16-function-expressions/article.md
index e5aefd78a..2d7a34330 100644
--- a/1-js/02-first-steps/16-function-expressions/article.md
+++ b/1-js/02-first-steps/16-function-expressions/article.md
@@ -12,7 +12,13 @@ function sayHi() {
E' disponibile un'altra sintassi per creare una funzione, chiamata *function expression*.
+<<<<<<< HEAD
La sintassi:
+=======
+It allows us to create a new function in the middle of any expression.
+
+For example:
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
```js
let sayHi = function() {
@@ -72,15 +78,20 @@ let sayHi = function() { // (1) create
alert( "Hello" );
};
-let func = sayHi;
+let func = sayHi; //(2)
// ...
```
Tutto funzionerebbe ugualmente. Risulta anche più chiaro cosa sta succedendo, giusto?
+<<<<<<< HEAD
````smart header="Perché c'è un punto e virgola alla fine?"
Vi starete chiedendo perché con la function expression bisogna mettere `;` alla fine, mentre con la dichiarazione di funzione non serve:
+=======
+````smart header="Why is there a semicolon at the end?"
+You might wonder, why do Function Expressions have a semicolon `;` at the end, but Function Declarations do not:
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
```js
function sayHi() {
@@ -135,13 +146,21 @@ function showCancel() {
ask("Do you agree?", showOk, showCancel);
```
+<<<<<<< HEAD
Queste funzioni possono essere molto utili. La principale differenza tra un'implementazione realistica e gli esempi sopra è che le funzioni "reali" utilizzano modalità più complesse per interagire con l'utente, non un semplice `confirm`. In ambiente browser, queste funzioni mostrano spesso delle finestre molto carine per gli input dell'utente. Ma questo è un altro discorso.
+=======
+In practice, such functions are quite useful. The major difference between a real-life `ask` and the example above is that real-life functions use more complex ways to interact with the user than a simple `confirm`. In the browser, such functions usually draw a nice-looking question window. But that's another story.
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
**Gli argomenti `showOk` e `showCancel` della `ask` sono chiamati *funzioni di richiamo* o semplicemente *callbacks*.**
L'idea è di passare una funzione e di "richiamarla" più tardi se necessario. Nel nostro caso `showOk` diventa la callback per la risposta "yes", e `showCancel` per la risposta "no".
+<<<<<<< HEAD
Possiamo utilizzare una function expression per scrivere la stessa funzione più concisamente:
+=======
+We can use Function Expressions to write an equivalent, shorter function:
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
```js run no-beautify
function ask(question, yes, no) {
@@ -179,7 +198,11 @@ Cerchiamo di elencare le differenze chiave tra Dichiarazioni ed Espressioni di F
Primo, la sintassi: come distinguerle nel codice.
+<<<<<<< HEAD
- *Dichiarazione di funzione:* una funzione, dichiarata come un'istruzione separata, nel flusso principale del programma.
+=======
+- *Function Declaration:* a function, declared as a separate statement, in the main code flow:
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
```js
// Dichiarazione di funzione
@@ -187,8 +210,13 @@ Primo, la sintassi: come distinguerle nel codice.
return a + b;
}
```
+<<<<<<< HEAD
- *Function expression:* una funzione, creata all'interno di un'espressione o all'interno di un altro costrutto. Qui, la funzione è creata alla destra dell' "espressione di assegnazione" `=`:
+=======
+- *Function Expression:* a function, created inside an expression or inside another syntax construct. Here, the function is created on the right side of the "assignment expression" `=`:
+
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
```js
// function expression
let sum = function(a, b) {
@@ -284,9 +312,15 @@ if (age < 18) {
welcome(); // \ (esegue)
*/!*
// |
+<<<<<<< HEAD
function welcome() { // |
alert("Hello!"); // | Dichiarazione di funzione disponibile
} // | ovunque nel blocco in cui è stata dichiarata
+=======
+ function welcome() { // |
+ alert("Hello!"); // | Function Declaration is available
+ } // | everywhere in the block where it's declared
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
// |
*!*
welcome(); // / (esegue)
@@ -294,7 +328,11 @@ if (age < 18) {
} else {
+<<<<<<< HEAD
function welcome() {
+=======
+ function welcome() {
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
alert("Greetings!");
}
}
@@ -352,8 +390,13 @@ welcome(); // ora funziona
```
+<<<<<<< HEAD
```smart header="Quando conviene scegliere una dichiarazione di funzione piuttosto di una function expression?"
Come regola fondamentale, quando abbiamo la necessità di dichiarare una funzione, la prima opzione da considerare è la dichiarazione di funzione. Fornisce maggiore libertà per quanto riguarda l'organizzazione del codice, poiché possiamo utilizzare la funzione anche prima della sua dichiarazione.
+=======
+```smart header="When to choose Function Declaration versus Function Expression?"
+As a rule of thumb, when we need to declare a function, the first thing to consider is Function Declaration syntax. It gives more freedom in how to organize our code, because we can call such functions before they are declared.
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
Risulta anche più facile vedere `function f(…) {…}`, nel codice, piuttosto di `let f = function(…) {…}`. La dichiarazione di funzione è più facile da individuare.
diff --git a/1-js/02-first-steps/17-arrow-functions-basics/article.md b/1-js/02-first-steps/17-arrow-functions-basics/article.md
index 1a1dc2a09..3d6f11556 100644
--- a/1-js/02-first-steps/17-arrow-functions-basics/article.md
+++ b/1-js/02-first-steps/17-arrow-functions-basics/article.md
@@ -33,7 +33,11 @@ let sum = function(a, b) {
alert( sum(1, 2) ); // 3
```
+<<<<<<< HEAD
Come puoi vedere `(a, b) => a + b` rappresenta una funzione che accetta due argomenti `a` e `b`. Al momento dell'esecuzione, questa valuta l'espressione `a + b` e restituisce il risultato.
+=======
+As you can see, `(a, b) => a + b` means a function that accepts two arguments named `a` and `b`. Upon the execution, it evaluates the expression `a + b` and returns the result.
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
- Se abbiamo un solo argomento, le parentesi che racchiudono gli argomenti possono essere omesse, abbreviando ulteriormente il codice.
@@ -48,7 +52,11 @@ Come puoi vedere `(a, b) => a + b` rappresenta una funzione che accetta due argo
alert( double(3) ); // 6
```
+<<<<<<< HEAD
- Se non ci sono argomenti, le parentesi saranno vuote (ma devono essere presenti):
+=======
+- If there are no arguments, parentheses are empty, but they must be present:
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
```js run
let sayHi = () => alert("Hello!");
@@ -64,7 +72,7 @@ Ad esempio, per creare dinamicamente una funzione:
let age = prompt("What is your age?", 18);
let welcome = (age < 18) ?
- () => alert('Hello') :
+ () => alert('Hello!') :
() => alert("Greetings!");
welcome();
@@ -76,9 +84,15 @@ Esse sono molto comode per semplici azioni su una riga, se siamo troppo pigri pe
## Arrow functions su più linee
+<<<<<<< HEAD
Gli esempi precedenti hanno preso argomenti alla sinistra di "=>" e con essi hanno valutato l'espressione a destra.
A volte abbiamo bisogno di qualcosa di un po' più complesso, come espressioni o dichiarazioni multiple. Anche questo è possibile, ma dovremo racchiuderle tra parentesi graffe ed usare un normale return.
+=======
+The arrow functions that we've seen so far were very simple. They took arguments from the left of `=>`, evaluated and returned the right-side expression with them.
+
+Sometimes we need a more complex function, with multiple expressions and statements. In that case, we can enclose them in curly braces. The major difference is that curly braces require a `return` within them to return a value (just like a regular function does).
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
In questo modo:
@@ -86,7 +100,11 @@ In questo modo:
let sum = (a, b) => { // le parentesi graffe aprono una funzione multilinea
let result = a + b;
*!*
+<<<<<<< HEAD
return result; // se usiamo le parentesi graffe abbiamo bisogno di un esplicito "return"
+=======
+ return result; // if we use curly braces, then we need an explicit "return"
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
*/!*
};
@@ -106,8 +124,15 @@ Per ora possiamo già utilizzarle per azioni su una riga sola e per callbacks.
## Summary
+<<<<<<< HEAD
Le arrow functions sono utili per azioni su una riga sola. Possono essere scritte in due modi:
1. Senza parentesi graffe: `(...args) => expression` -- la parte destra è un'espressione: la funzione la valuta e restituisce il risultato.
2. Con parentesi graffe: `(...args) => { body }` -- le parentesi ci permettono di scrivere comandi multipli all'interno della funzione, ma abbiamo bisogno di dichiarare esplicitamente
`return` affinché sia ritornato qualcosa.
+=======
+Arrow functions are handy for simple actions, especially for one-liners. They come in two flavors:
+
+1. Without curly braces: `(...args) => expression` -- the right side is an expression: the function evaluates it and returns the result. Parentheses can be omitted, if there's only a single argument, e.g. `n => n*2`.
+2. With curly braces: `(...args) => { body }` -- brackets allow us to write multiple statements inside the function, but we need an explicit `return` to return something.
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
diff --git a/1-js/02-first-steps/18-javascript-specials/article.md b/1-js/02-first-steps/18-javascript-specials/article.md
index 1f891fd26..d91311f41 100644
--- a/1-js/02-first-steps/18-javascript-specials/article.md
+++ b/1-js/02-first-steps/18-javascript-specials/article.md
@@ -55,7 +55,11 @@ Per abilitare completamente tutte le caratteristiche del moderno JavaScript, dov
La direttiva deve essere posta all'inizio di ogni script o all'inizio di una funzione.
+<<<<<<< HEAD
Senza `"use strict"`, tutto continuerebbe a funzionare, ma alcune caratteristiche si comporterebbero in vecchio-stile, per retrocompatibilità. Generalmente si preferisce la modalità con i comportamenti moderni.
+=======
+Without `"use strict"`, everything still works, but some features behave in the old-fashioned, "compatible" way. We'd generally prefer the modern behavior.
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
Alcune caratteristiche moderne del linguaggio (come le classi che studieremo più avanti) attivano automaticamente la modalità script.
@@ -103,6 +107,7 @@ Di più in: 253
od essere inferiori di -253
. Poiché i BigInt vengono utilizzati in alcune aree speciali, gli abbiamo dedicato un capitolo (253-1)
or be less than -(253-1)
, as we mentioned earlier in the chapter func`string`
. La funzione `func` viene chiamata automaticamente, gli viene passata la "string", può essere cosi trattata dalla funzione. Potete approfondire leggendo la [documentazione](mdn:/JavaScript/Reference/Template_literals#Tagged_templates). Questo viene chiamata "funzione template". Con questa caratteristica diventa più facile raccogliere stringhe da passare a funzioni, ma è raramente utilizzata.
+=======
+Single and double quotes come from ancient times of language creation, when the need for multiline strings was not taken into account. Backticks appeared much later and thus are more versatile.
+
+Backticks also allow us to specify a "template function" before the first backtick. The syntax is: func`string`
. The function `func` is called automatically, receives the string and embedded expressions and can process them. This feature is called "tagged templates", it's rarely seen, but you can read about it in the MDN: [Template literals](mdn:/JavaScript/Reference/Template_literals#Tagged_templates).
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
## Caratteri speciali
@@ -57,10 +63,17 @@ E' comunque possibile creare stringhe multilinea con singoli apici utilizzando i
```js run
let guestList = "Guests:\n * John\n * Pete\n * Mary";
+<<<<<<< HEAD
alert(guestList); // una lista di guest multi riga
```
Ad esempio, queste due funzioni portano allo stesso risultato:
+=======
+alert(guestList); // a multiline list of guests, same as above
+```
+
+As a simpler example, these two lines are equal, just written differently:
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
```js run
let str1 = "Hello\nWorld"; // due righe utilizzando il "carattere nuova riga"
@@ -70,6 +83,7 @@ let str2 = `Hello
World`;
```
+<<<<<<< HEAD
Ci sono altri caratteri "speciali" meno comuni. Qui una lista:
| Carattere | Descrizione |
@@ -95,6 +109,28 @@ alert( "\u{1F60D}" ); // 😍, un simbolo di faccia sorridente (long unicode)
Tutti i caratteri speciali iniziano con un backslash `\`. Che viene anche chiamato "carattere di escape".
Dobbiamo utilizzarlo anche se abbiamo intenzione di inserire un apice all'interno della stringa.
+=======
+There are other, less common special characters:
+
+| Character | Description |
+|-----------|-------------|
+|`\n`|New line|
+|`\r`|In Windows text files a combination of two characters `\r\n` represents a new break, while on non-Windows OS it's just `\n`. That's for historical reasons, most Windows software also understands `\n`. |
+|`\'`, `\"`, \\`
|Quotes|
+|`\\`|Backslash|
+|`\t`|Tab|
+|`\b`, `\f`, `\v`| Backspace, Form Feed, Vertical Tab -- mentioned for completeness, coming from old times, not used nowadays (you can forget them right now). |
+
+As you can see, all special characters start with a backslash character `\`. It is also called an "escape character".
+
+Because it's so special, if we need to show an actual backslash `\` within the string, we need to double it:
+
+```js run
+alert( `The backslash: \\` ); // The backslash: \
+```
+
+So-called "escaped" quotes `\'`, `\"`, \\`
are used to insert a quote into the same-quoted string.
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
Ad esempio:
@@ -107,9 +143,10 @@ Avete visto che abbiamo inserito un backslash `\'` prima dell'apice interno, alt
Ovviamente, questo è valido per un apice uguale a quello utilizzato in apertura. Quindi, possiamo optare per una soluzione più elegante, ad esempio i doppi apici o i backticks:
```js run
-alert( `I'm the Walrus!` ); // I'm the Walrus!
+alert( "I'm the Walrus!" ); // I'm the Walrus!
```
+<<<<<<< HEAD
Da notare che il backslash `\` ha l'unico scopo di aiutare JavaScript nella lettura della stringa, questo verrà poi rimosso. La stringa in memoria non avrà `\`. Lo avrete sicuramente notato con gli `alert` dei vari esempi sopra.
Ma se volessimo realmente mostrare un backslash `\` dentro la stringa?
@@ -119,6 +156,9 @@ E' possibile farlo, ma dobbiamo esplicitarlo con un doppio backslash `\\`:
```js run
alert( `The backslash: \\` ); // The backslash: \
```
+=======
+Besides these special characters, there's also a special notation for Unicode codes `\u…`, it's rarely used and is covered in the optional chapter about [Unicode](info:unicode).
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
## String length
@@ -133,33 +173,55 @@ Da notare che `\n` è contato come unico carattere "speciale", quindi la lunghez
```warn header="`length` è una proprietà"
Alcune persone abituate ad altri linguaggi possono confondere al chiamata `str.length()` con `str.length`. Questo è un errore.
+<<<<<<< HEAD
Infatti `str.length` è una proprietà numerica, non una funzione. Non c'è alcun bisogno delle parentesi.
+=======
+Please note that `str.length` is a numeric property, not a function. There is no need to add parenthesis after it. Not `.length()`, but `.length`.
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
```
## Accesso ai caratteri
+<<<<<<< HEAD
Per ottenere un carattere alla posizione `pos`, si utilizzano le parentesi quadre `[pos]` oppure la chiamata al metodo [str.charAt(pos)](mdn:js/String/charAt). Il primo carattere parte dalla posizione zero:
+=======
+To get a character at position `pos`, use square brackets `[pos]` or call the method [str.at(pos)](mdn:js/String/at). The first character starts from the zero position:
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
```js run
let str = `Hello`;
// il primo carattere
alert( str[0] ); // H
-alert( str.charAt(0) ); // H
+alert( str.at(0) ); // H
// l'ultimo carattere
alert( str[str.length - 1] ); // o
+alert( str.at(-1) );
```
+<<<<<<< HEAD
L'utilizzo delle parentesi quadre è il modo più classico per accedere ad un carattere, mentre `charAt` esiste principalmente per ragioni storiche.
L'unica differenza sta nel comportamento in casi di carattere non trovato, `[]` ritorna `undefined`, e `charAt` ritorna una stringa vuota:
+=======
+As you can see, the `.at(pos)` method has a benefit of allowing negative position. If `pos` is negative, then it's counted from the end of the string.
+
+So `.at(-1)` means the last character, and `.at(-2)` is the one before it, etc.
+
+The square brackets always return `undefined` for negative indexes, for instance:
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
```js run
let str = `Hello`;
+<<<<<<< HEAD
alert( str[1000] ); // undefined
alert( str.charAt(1000) ); // '' (una stringa vuota)
+=======
+alert( str[-2] ); // undefined
+alert( str.at(-2) ); // l
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
```
Possiamo iterare sui caratteri utilizzando `for..of`:
@@ -208,7 +270,7 @@ alert( 'Interface'.toLowerCase() ); // interface
Altrimenti, possiamo agire anche su un singolo carattere:
-```js
+```js run
alert( 'Interface'[0].toLowerCase() ); // 'i'
```
@@ -305,6 +367,7 @@ if (str.indexOf("Widget") != -1) {
}
```
+<<<<<<< HEAD
#### Il trucco del NOT bit a bit
Uno dei trucchi più utilizzati è l'operatore di [NOT bit a bit](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_NOT) `~`. Questo converte il numero ad un intero in 32bit (rimuovendo la parte decimale se presente) e successivamente inverte tutti i bit.
@@ -343,6 +406,8 @@ Per essere precisi, numeri molto grandi vengono troncati a 32bit dall'operatore
Attualmente questo trucco lo troviamo solamente nei codici vecchi, poiché JavaScript moderno fornisce un metodo dedicato, `.includes`(vedi sotto).
+=======
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
### includes, startsWith, endsWith
Un metodo più moderno come [str.includes(substr, pos)](mdn:js/String/includes) ritorna `true/false` basandosi solo sull'aver trovato in `str` la `substr`.
@@ -365,8 +430,13 @@ alert( "Midget".includes("id", 3) ); // false, dalla posizione 3 non c'è "id"
I metodi [str.startsWith](mdn:js/String/startsWith) e [str.endsWith](mdn:js/String/endsWith) fanno esattamente ciò che dicono i loro nomi:
```js run
+<<<<<<< HEAD
alert( "Widget".startsWith("Wid") ); // true, "Widget" inizia con "Wid"
alert( "Widget".endsWith("get") ); // true, "Widget" finisce con "get"
+=======
+alert( "*!*Wid*/!*get".startsWith("Wid") ); // true, "Widget" starts with "Wid"
+alert( "Wid*!*get*/!*".endsWith("get") ); // true, "Widget" ends with "get"
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
```
## Estrarre una sotto-stringa
@@ -401,9 +471,15 @@ Ci sono 3 metodi in JavaScript per estrarre una sotto-stringa: `substring`, `sub
```
`str.substring(start [, end])`
+<<<<<<< HEAD
: Ritorna la parte di stringa *compresa tra* `start` e `end`.
E' molto simile a `slice`, ma consente di avere `start` maggiore di `end`.
+=======
+: Returns the part of the string *between* `start` and `end` (not including `end`).
+
+ This is almost the same as `slice`, but it allows `start` to be greater than `end` (in this case it simply swaps `start` and `end` values).
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
Ad esempio:
@@ -439,19 +515,37 @@ Ci sono 3 metodi in JavaScript per estrarre una sotto-stringa: `substring`, `sub
alert( str.substr(-4, 2) ); // gi, dalla quarta posizione prende 4 caratteri
```
+<<<<<<< HEAD
Ricapitoliamo questi metodi per evitare confusione:
+=======
+ This method resides in the [Annex B](https://tc39.es/ecma262/#sec-string.prototype.substr) of the language specification. It means that only browser-hosted Javascript engines should support it, and it's not recommended to use it. In practice, it's supported everywhere.
+
+Let's recap these methods to avoid any confusion:
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
| metodo | selezione... | negativi |
|--------|-----------|-----------|
+<<<<<<< HEAD
| `slice(start, end)` | da `start` a `end` (`end` escluso) | indici negativi ammessi |
| `substring(start, end)` | tra `start` e `end` | valori negativi valgono come `0` |
| `substr(start, length)` | da `start` per `length` caratteri | consente indice di `start` negativo |
+=======
+| `slice(start, end)` | from `start` to `end` (not including `end`) | allows negatives |
+| `substring(start, end)` | between `start` and `end` (not including `end`)| negative values mean `0` |
+| `substr(start, length)` | from `start` get `length` characters | allows negative `start` |
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
+<<<<<<< HEAD
```smart header="Quale scegliere?"
Tutti i metodi esaminati possono portare a termine il lavoro. Formalmente, `substr` ha un piccolo inconveniente: non è descritto nelle specifiche del core JavaScript, ma in quelle di Annex B, che copre solo le caratteristiche utili nello sviluppo browser. Quindi ambienti diversi dal browser potrebbero non supportarla. Ma nella pratica viene utilizzata ovunque.
L'autore della guida si trova spesso ad utilizzare il metodo `slice`.
+=======
+Of the other two variants, `slice` is a little bit more flexible, it allows negative arguments and shorter to write.
+
+So, for practical use it's enough to remember only `slice`.
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
```
## Confronto tra stringhe
@@ -474,6 +568,7 @@ Sebbene ci siano dei casi particolari.
Questo potrebbe portare a strani risultati se provassimo ad ordinare le città per nome. Solitamente ci si aspetta di trovare `Zealand` dopo `Österreich`.
+<<<<<<< HEAD
Per capire cosa succede, dobbiamo guardare alla rappresentazione interna delle stringhe in JavaScript.
Tutte le stringhe vengono codificate utilizzando [UTF-16](https://en.wikipedia.org/wiki/UTF-16). Cioè: ogni carattere ha un suo codice numerico. Ci sono alcuni metodi che consentono di ottenere il carattere dal codice (e viceversa).
@@ -484,7 +579,20 @@ Tutte le stringhe vengono codificate utilizzando [UTF-16](https://en.wikipedia.o
```js run
// lettere di timbro differente possiedono codici differenti
alert( "z".codePointAt(0) ); // 122
+=======
+To understand what happens, we should be aware that strings in Javascript are encoded using [UTF-16](https://en.wikipedia.org/wiki/UTF-16). That is: each character has a corresponding numeric code.
+
+There are special methods that allow to get the character for the code and back:
+
+`str.codePointAt(pos)`
+: Returns a decimal number representing the code for the character at position `pos`:
+
+ ```js run
+ // different case letters have different codes
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
alert( "Z".codePointAt(0) ); // 90
+ alert( "z".codePointAt(0) ); // 122
+ alert( "z".codePointAt(0).toString(16) ); // 7a (if we need a hexadecimal value)
```
`String.fromCodePoint(code)`
@@ -492,6 +600,7 @@ Tutte le stringhe vengono codificate utilizzando [UTF-16](https://en.wikipedia.o
```js run
alert( String.fromCodePoint(90) ); // Z
+<<<<<<< HEAD
```
Possiamo anche aggiungere caratteri unicode tramite il loro codice utilizzando `\u` seguito dal codice esadecimale:
@@ -499,6 +608,9 @@ Tutte le stringhe vengono codificate utilizzando [UTF-16](https://en.wikipedia.o
```js run
// 90 è 5a nel sistema esadecimale
alert( '\u005a' ); // Z
+=======
+ alert( String.fromCodePoint(0x5a) ); // Z (we can also use a hex value as an argument)
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
```
Ora vediamo i caratteri con il codice compreso tra `65..220` (l'alfabeto latino e qualche extra) creando una stringa:
@@ -510,6 +622,7 @@ for (let i = 65; i <= 220; i++) {
str += String.fromCodePoint(i);
}
alert( str );
+// Output:
// ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
// ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜ
```
@@ -529,7 +642,11 @@ L'algoritmo più corretto da utilizzare per confrontare stringhe è più comples
Quindi il browser deve sapere quale lingua utilizzare nel confronto.
+<<<<<<< HEAD
Fortunatamente, tutti i browser moderni (IE10 richiede una libreria esterna [Intl.js](https://github.com/andyearnshaw/Intl.js/)) supportano lo standard internazionale [ECMA-402](http://www.ecma-international.org/ecma-402/1.0/ECMA-402.pdf).
+=======
+Luckily, modern browsers support the internationalization standard [ECMA-402](https://www.ecma-international.org/publications-and-standards/standards/ecma-402/).
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
Questo fornisce uno speciale metodo per confrontare stringhe in lingue diverse, seguendo delle regole.
@@ -547,6 +664,7 @@ alert( 'Österreich'.localeCompare('Zealand') ); // -1
Questo metodo in realtà ha due argomenti opzionali specificati nella [documentazione](mdn:js/String/localeCompare), che consentono di specificare la lingua (di default viene presa dall'ambiente) e impostare delle regole aggiuntive come il timbro delle lettere, oppure se `"a"` e `"á"` dovrebbero essere trattate ugualmente etc.
+<<<<<<< HEAD
## Internamente, Unicode
```warn header="Apprendimento avanzato"
@@ -653,6 +771,17 @@ Se volete approfondire il tema della normalizzazione e le sue varianti -- vengon
## Riepilogo
+=======
+## Summary
+
+- There are 3 types of quotes. Backticks allow a string to span multiple lines and embed expressions `${…}`.
+- We can use special characters, such as a line break `\n`.
+- To get a character, use: `[]` or `at` method.
+- To get a substring, use: `slice` or `substring`.
+- To lowercase/uppercase a string, use: `toLowerCase/toUpperCase`.
+- To look for a substring, use: `indexOf`, or `includes/startsWith/endsWith` for simple checks.
+- To compare strings according to the language, use: `localeCompare`, otherwise they are compared by character codes.
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
- Ci sono 3 tipi di apici. Le backticks consentono stringhe multi-linea ed espressioni integrate.
- Le stringhe in JavaScript vengono codificate usando UTF-16.
@@ -665,8 +794,14 @@ Se volete approfondire il tema della normalizzazione e le sue varianti -- vengon
Ci sono molti altri metodi utili per operare con le stringhe:
+<<<<<<< HEAD
- `str.trim()` -- rimuove gli spazi all'inizio e alla fine della stringa.
- `str.repeat(n)` -- ripete la stringa `n` volte.
- ...e molto altro. Guarda il [manuale](mdn:js/String) per maggiori dettagli.
Le stringhe possiedono anche metodi per eseguire ricerche/rimpiazzi con le regular expression. Ma l'argomento merita un capitolo separato, quindi ci ritorneremo più avanti, alert
will trigger immediately.
+
+## FinalizationRegistry
+
+Now it is time to talk about finalizers. Before we move on, let's clarify the terminology:
+
+**Cleanup callback (finalizer)** - is a function that is executed, when an object, registered in the `FinalizationRegistry`, is deleted from memory by the garbage collector.
+
+Its purpose - is to provide the ability to perform additional operations, related to the object, after it has been finally deleted from memory.
+
+**Registry** (or `FinalizationRegistry`) - is a special object in JavaScript that manages the registration and unregistration of objects and their cleanup callbacks.
+
+This mechanism allows registering an object to track and associate a cleanup callback with it.
+Essentially it is a structure that stores information about registered objects and their cleanup callbacks, and then automatically invokes those callbacks when the objects are deleted from memory.
+
+To create an instance of the `FinalizationRegistry`, it needs to call its constructor, which takes a single argument - the cleanup callback (finalizer).
+
+Syntax:
+
+```js
+function cleanupCallback(heldValue) {
+ // cleanup callback code
+}
+
+const registry = new FinalizationRegistry(cleanupCallback);
+```
+
+Here:
+
+- `cleanupCallback` - a cleanup callback that will be automatically called when a registered object is deleted from memory.
+- `heldValue` - the value that is passed as an argument to the cleanup callback. If `heldValue` is an object, the registry keeps a strong reference to it.
+- `registry` - an instance of `FinalizationRegistry`.
+
+`FinalizationRegistry` methods:
+
+- `register(target, heldValue [, unregisterToken])` - used to register objects in the registry.
+
+ `target` - the object being registered for tracking. If the `target` is garbage collected, the cleanup callback will be called with `heldValue` as its argument.
+
+ Optional `unregisterToken` – an unregistration token. It can be passed to unregister an object before the garbage collector deletes it. Typically, the `target` object is used as `unregisterToken`, which is the standard practice.
+- `unregister(unregisterToken)` - the `unregister` method is used to unregister an object from the registry. It takes one argument - `unregisterToken` (the unregister token that was obtained when registering the object).
+
+Now let's move on to a simple example. Let's use the already-known `user` object and create an instance of `FinalizationRegistry`:
+
+```js
+let user = { name: "John" };
+
+const registry = new FinalizationRegistry((heldValue) => {
+ console.log(`${heldValue} has been collected by the garbage collector.`);
+});
+```
+
+Then, we will register the object, that requires a cleanup callback by calling the `register` method:
+
+```js
+registry.register(user, user.name);
+```
+
+The registry does not keep a strong reference to the object being registered, as this would defeat its purpose. If the registry kept a strong reference, then the object would never be garbage collected.
+
+If the object is deleted by the garbage collector, our cleanup callback may be called at some point in the future, with the `heldValue` passed to it:
+
+```js
+// When the user object is deleted by the garbage collector, the following message will be printed in the console:
+"John has been collected by the garbage collector."
+```
+
+There are also situations where, even in implementations that use a cleanup callback, there is a chance that it will not be called.
+
+For example:
+- When the program fully terminates its operation (for example, when closing a tab in a browser).
+- When the `FinalizationRegistry` instance itself is no longer reachable to JavaScript code.
+ If the object that creates the `FinalizationRegistry` instance goes out of scope or is deleted, the cleanup callbacks registered in that registry might also not be invoked.
+
+## Caching with FinalizationRegistry
+
+Returning to our *weak* cache example, we can notice the following:
+- Even though the values wrapped in the `WeakRef` have been collected by the garbage collector, there is still an issue of "memory leakage" in the form of the remaining keys, whose values have been collected by the garbage collector.
+
+Here is an improved caching example using `FinalizationRegistry`:
+
+```js
+function fetchImg() {
+ // abstract function for downloading images...
+}
+
+function weakRefCache(fetchImg) {
+ const imgCache = new Map();
+
+ *!*
+ const registry = new FinalizationRegistry((imgName) => { // (1)
+ const cachedImg = imgCache.get(imgName);
+ if (cachedImg && !cachedImg.deref()) imgCache.delete(imgName);
+ });
+ */!*
+
+ return (imgName) => {
+ const cachedImg = imgCache.get(imgName);
+
+ if (cachedImg?.deref()) {
+ return cachedImg?.deref();
+ }
+
+ const newImg = fetchImg(imgName);
+ imgCache.set(imgName, new WeakRef(newImg));
+ *!*
+ registry.register(newImg, imgName); // (2)
+ */!*
+
+ return newImg;
+ };
+}
+
+const getCachedImg = weakRefCache(fetchImg);
+```
+
+1. To manage the cleanup of "dead" cache entries, when the associated `WeakRef` objects are collected by the garbage collector, we create a `FinalizationRegistry` cleanup registry.
+
+ The important point here is, that in the cleanup callback, it should be checked, if the entry was deleted by the garbage collector and not re-added, in order not to delete a "live" entry.
+2. Once the new value (image) is downloaded and put into the cache, we register it in the finalizer registry to track the `WeakRef` object.
+
+This implementation contains only actual or "live" key/value pairs.
+In this case, each `WeakRef` object is registered in the `FinalizationRegistry`.
+And after the objects are cleaned up by the garbage collector, the cleanup callback will delete all `undefined` values.
+
+Here is a visual representation of the updated code:
+
+
+
+A key aspect of the updated implementation is that finalizers allow parallel processes to be created between the "main" program and cleanup callbacks.
+In the context of JavaScript, the "main" program - is our JavaScript-code, that runs and executes in our application or web page.
+
+Hence, from the moment an object is marked for deletion by the garbage collector, and to the actual execution of the cleanup callback, there may be a certain time gap.
+It is important to understand that during this time gap, the main program can make any changes to the object or even bring it back to memory.
+
+That's why, in the cleanup callback, we must check to see if an entry has been added back to the cache by the main program to avoid deleting "live" entries.
+Similarly, when searching for a key in the cache, there is a chance that the value has been deleted by the garbage collector, but the cleanup callback has not been executed yet.
+
+Such situations require special attention if you are working with `FinalizationRegistry`.
+
+## Using WeakRef and FinalizationRegistry in practice
+
+Moving from theory to practice, imagine a real-life scenario, where a user synchronizes their photos on a mobile device with some cloud service
+(such as [iCloud](https://en.wikipedia.org/wiki/ICloud) or [Google Photos](https://en.wikipedia.org/wiki/Google_Photos)),
+and wants to view them from other devices. In addition to the basic functionality of viewing photos, such services offer a lot of additional features, for example:
+
+- Photo editing and video effects.
+- Creating "memories" and albums.
+- Video montage from a series of photos.
+- ...and much more.
+
+Here, as an example, we will use a fairly primitive implementation of such a service.
+The main point - is to show a possible scenario of using `WeakRef` and `FinalizationRegistry` together in real life.
+
+Here is what it looks like:
+
+
+
+weakRefCache
function checks whether the required image is in the cache.
+If not, it downloads it from the cloud and puts it in the cache for further use.
+This happens for each selected image:
+Messages:
+ +Logger:
+Logger:
'; +}; + +const downloadCollage = () => { + const date = new Date(); + const fileName = `Collage-${date.getDay()}-${date.getMonth()}-${date.getFullYear()}.png`; + const img = canvasEl.toDataURL("image/png"); + const link = document.createElement("a"); + link.download = fileName; + link.href = img; + link.click(); + link.remove(); +}; + +const changeLayout = ({ target }) => { + state.currentLayout = JSON.parse(target.value); +}; + +// Listeners. +selectEl.addEventListener("change", changeLayout); +createCollageBtn.addEventListener("click", createCollage); +startOverBtn.addEventListener("click", startOver); +downloadBtn.addEventListener("click", downloadCollage); diff --git a/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/utils.js b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/utils.js new file mode 100644 index 000000000..f0140c116 --- /dev/null +++ b/1-js/99-js-misc/07-weakref-finalizationregistry/weakref-finalizationregistry.view/utils.js @@ -0,0 +1,321 @@ +const loggerContainerEl = document.querySelector(".loggerContainer"); + +export const images = [ + { + img: "https://images.unsplash.com/photo-1471357674240-e1a485acb3e1", + }, + { + img: "https://images.unsplash.com/photo-1589118949245-7d38baf380d6", + }, + { + img: "https://images.unsplash.com/photo-1527631746610-bca00a040d60", + }, + { + img: "https://images.unsplash.com/photo-1500835556837-99ac94a94552", + }, + { + img: "https://images.unsplash.com/photo-1503220317375-aaad61436b1b", + }, + { + img: "https://images.unsplash.com/photo-1501785888041-af3ef285b470", + }, + { + img: "https://images.unsplash.com/photo-1528543606781-2f6e6857f318", + }, + { + img: "https://images.unsplash.com/photo-1523906834658-6e24ef2386f9", + }, + { + img: "https://images.unsplash.com/photo-1539635278303-d4002c07eae3", + }, + { + img: "https://images.unsplash.com/photo-1533105079780-92b9be482077", + }, + { + img: "https://images.unsplash.com/photo-1516483638261-f4dbaf036963", + }, + { + img: "https://images.unsplash.com/photo-1502791451862-7bd8c1df43a7", + }, + { + img: "https://plus.unsplash.com/premium_photo-1663047367140-91adf819d007", + }, + { + img: "https://images.unsplash.com/photo-1506197603052-3cc9c3a201bd", + }, + { + img: "https://images.unsplash.com/photo-1517760444937-f6397edcbbcd", + }, + { + img: "https://images.unsplash.com/photo-1518684079-3c830dcef090", + }, + { + img: "https://images.unsplash.com/photo-1505832018823-50331d70d237", + }, + { + img: "https://images.unsplash.com/photo-1524850011238-e3d235c7d4c9", + }, + { + img: "https://plus.unsplash.com/premium_photo-1661277758451-b5053309eea1", + }, + { + img: "https://images.unsplash.com/photo-1541410965313-d53b3c16ef17", + }, + { + img: "https://images.unsplash.com/photo-1528702748617-c64d49f918af", + }, + { + img: "https://images.unsplash.com/photo-1502003148287-a82ef80a6abc", + }, + { + img: "https://plus.unsplash.com/premium_photo-1661281272544-5204ea3a481a", + }, + { + img: "https://images.unsplash.com/photo-1503457574462-bd27054394c1", + }, + { + img: "https://images.unsplash.com/photo-1499363536502-87642509e31b", + }, + { + img: "https://images.unsplash.com/photo-1551918120-9739cb430c6d", + }, + { + img: "https://plus.unsplash.com/premium_photo-1661382219642-43e54f7e81d7", + }, + { + img: "https://images.unsplash.com/photo-1497262693247-aa258f96c4f5", + }, + { + img: "https://images.unsplash.com/photo-1525254134158-4fd5fdd45793", + }, + { + img: "https://plus.unsplash.com/premium_photo-1661274025419-4c54107d5c48", + }, + { + img: "https://images.unsplash.com/photo-1553697388-94e804e2f0f6", + }, + { + img: "https://images.unsplash.com/photo-1574260031597-bcd9eb192b4f", + }, + { + img: "https://images.unsplash.com/photo-1536323760109-ca8c07450053", + }, + { + img: "https://images.unsplash.com/photo-1527824404775-dce343118ebc", + }, + { + img: "https://images.unsplash.com/photo-1612278675615-7b093b07772d", + }, + { + img: "https://images.unsplash.com/photo-1522010675502-c7b3888985f6", + }, + { + img: "https://images.unsplash.com/photo-1501555088652-021faa106b9b", + }, + { + img: "https://plus.unsplash.com/premium_photo-1669223469435-27e091439169", + }, + { + img: "https://images.unsplash.com/photo-1506012787146-f92b2d7d6d96", + }, + { + img: "https://images.unsplash.com/photo-1511739001486-6bfe10ce785f", + }, + { + img: "https://images.unsplash.com/photo-1553342385-111fd6bc6ab3", + }, + { + img: "https://images.unsplash.com/photo-1516546453174-5e1098a4b4af", + }, + { + img: "https://images.unsplash.com/photo-1527142879-95b61a0b8226", + }, + { + img: "https://images.unsplash.com/photo-1520466809213-7b9a56adcd45", + }, + { + img: "https://images.unsplash.com/photo-1516939884455-1445c8652f83", + }, + { + img: "https://images.unsplash.com/photo-1545389336-cf090694435e", + }, + { + img: "https://plus.unsplash.com/premium_photo-1669223469455-b7b734c838f4", + }, + { + img: "https://images.unsplash.com/photo-1454391304352-2bf4678b1a7a", + }, + { + img: "https://images.unsplash.com/photo-1433838552652-f9a46b332c40", + }, + { + img: "https://images.unsplash.com/photo-1506125840744-167167210587", + }, + { + img: "https://images.unsplash.com/photo-1522199873717-bc67b1a5e32b", + }, + { + img: "https://images.unsplash.com/photo-1495904786722-d2b5a19a8535", + }, + { + img: "https://images.unsplash.com/photo-1614094082869-cd4e4b2905c7", + }, + { + img: "https://images.unsplash.com/photo-1474755032398-4b0ed3b2ae5c", + }, + { + img: "https://images.unsplash.com/photo-1501554728187-ce583db33af7", + }, + { + img: "https://images.unsplash.com/photo-1515859005217-8a1f08870f59", + }, + { + img: "https://images.unsplash.com/photo-1531141445733-14c2eb7d4c1f", + }, + { + img: "https://images.unsplash.com/photo-1500259783852-0ca9ce8a64dc", + }, + { + img: "https://images.unsplash.com/photo-1510662145379-13537db782dc", + }, + { + img: "https://images.unsplash.com/photo-1573790387438-4da905039392", + }, + { + img: "https://images.unsplash.com/photo-1512757776214-26d36777b513", + }, + { + img: "https://images.unsplash.com/photo-1518855706573-84de4022b69b", + }, + { + img: "https://images.unsplash.com/photo-1500049242364-5f500807cdd7", + }, + { + img: "https://images.unsplash.com/photo-1528759335187-3b683174c86a", + }, +]; +export const THUMBNAIL_PARAMS = "w=240&h=240&fit=crop&auto=format"; + +// Console styles. +export const CONSOLE_BASE_STYLES = [ + "font-size: 12px", + "padding: 4px", + "border: 2px solid #5a5a5a", + "color: white", +].join(";"); +export const CONSOLE_PRIMARY = [ + CONSOLE_BASE_STYLES, + "background-color: #13315a", +].join(";"); +export const CONSOLE_SUCCESS = [ + CONSOLE_BASE_STYLES, + "background-color: #385a4e", +].join(";"); +export const CONSOLE_ERROR = [ + CONSOLE_BASE_STYLES, + "background-color: #5a1a24", +].join(";"); + +// Layouts. +export const LAYOUT_4_COLUMNS = { + name: "Layout 4 columns", + columns: 4, + itemWidth: 240, + itemHeight: 240, +}; +export const LAYOUT_8_COLUMNS = { + name: "Layout 8 columns", + columns: 8, + itemWidth: 240, + itemHeight: 240, +}; +export const LAYOUTS = [LAYOUT_4_COLUMNS, LAYOUT_8_COLUMNS]; + +export const createImageFile = async (src) => + new Promise((resolve, reject) => { + const img = new Image(); + img.src = src; + img.onload = () => resolve(img); + img.onerror = () => reject(new Error("Failed to construct image.")); + }); + +export const loadImage = async (url) => { + try { + const response = await fetch(url); + if (!response.ok) { + throw new Error(String(response.status)); + } + + return await response.blob(); + } catch (e) { + console.log(`%cFETCHED_FAILED: ${e}`, CONSOLE_ERROR); + } +}; + +export const weakRefCache = (fetchImg) => { + const imgCache = new Map(); + const registry = new FinalizationRegistry(({ imgName, size, type }) => { + const cachedImg = imgCache.get(imgName); + if (cachedImg && !cachedImg.deref()) { + imgCache.delete(imgName); + console.log( + `%cCLEANED_IMAGE: Url: ${imgName}, Size: ${size}, Type: ${type}`, + CONSOLE_ERROR, + ); + + const logEl = document.createElement("div"); + logEl.classList.add("logger-item", "logger--error"); + logEl.innerHTML = `CLEANED_IMAGE: Url: ${imgName}, Size: ${size}, Type: ${type}`; + loggerContainerEl.appendChild(logEl); + loggerContainerEl.scrollTop = loggerContainerEl.scrollHeight; + } + }); + + return async (imgName) => { + const cachedImg = imgCache.get(imgName); + + if (cachedImg?.deref() !== undefined) { + console.log( + `%cCACHED_IMAGE: Url: ${imgName}, Size: ${cachedImg.size}, Type: ${cachedImg.type}`, + CONSOLE_SUCCESS, + ); + + const logEl = document.createElement("div"); + logEl.classList.add("logger-item", "logger--success"); + logEl.innerHTML = `CACHED_IMAGE: Url: ${imgName}, Size: ${cachedImg.size}, Type: ${cachedImg.type}`; + loggerContainerEl.appendChild(logEl); + loggerContainerEl.scrollTop = loggerContainerEl.scrollHeight; + + return cachedImg?.deref(); + } + + const newImg = await fetchImg(imgName); + console.log( + `%cFETCHED_IMAGE: Url: ${imgName}, Size: ${newImg.size}, Type: ${newImg.type}`, + CONSOLE_PRIMARY, + ); + + const logEl = document.createElement("div"); + logEl.classList.add("logger-item", "logger--primary"); + logEl.innerHTML = `FETCHED_IMAGE: Url: ${imgName}, Size: ${newImg.size}, Type: ${newImg.type}`; + loggerContainerEl.appendChild(logEl); + loggerContainerEl.scrollTop = loggerContainerEl.scrollHeight; + + imgCache.set(imgName, new WeakRef(newImg)); + registry.register(newImg, { + imgName, + size: newImg.size, + type: newImg.type, + }); + + return newImg; + }; +}; + +export const stateObj = { + loading: false, + drawing: true, + collageRendered: false, + currentLayout: LAYOUTS[0], + selectedImages: new Set(), +}; diff --git a/2-ui/1-document/01-browser-environment/article.md b/2-ui/1-document/01-browser-environment/article.md index 43f558c07..c0ba3a112 100644 --- a/2-ui/1-document/01-browser-environment/article.md +++ b/2-ui/1-document/01-browser-environment/article.md @@ -1,10 +1,18 @@ # Il Browser come ambiente, specifiche +<<<<<<< HEAD Il linguaggio JavaScript è stato inizialmente creato per i browser. Da allora, si è evoluto fino a diventare un linguaggio adatto a molte piattaforme e differenti usi. La piattaforma di utilizzo può essere un browser, un web-server, una lavatrice o un qualunque altro tipo di *host*. Ognuno di essi fornisce delle funzionalità specifiche alla piattaforma stessa. Secondo la specifica JavaScript questa è la definizione di *ambiente host* Un ambiente host, oltre alle funzionalità core del linguaggio, fornisce oggetti e funzioni specifiche della piattaforma. I browser web, ad esempio, permettono di interagire con le pagine web, mentre Node.JS fornisce funzionalità dedicate al server e così via. +======= +The JavaScript language was initially created for web browsers. Since then, it has evolved into a language with many uses and platforms. + +A platform may be a browser, or a web-server or another *host*, or even a "smart" coffee machine if it can run JavaScript. Each of these provides platform-specific functionality. The JavaScript specification calls that a *host environment*. + +A host environment provides its own objects and functions in addition to the language core. Web browsers give a means to control web pages. Node.js provides server-side features, and so on. +>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9 Di seguito una panoramica di cosa succede quando JavaScript viene eseguito nel browser: @@ -15,7 +23,11 @@ C'è un oggetto "padre" chiamato `window` che ha due ruoli: 1. Il primo è quello di essere un oggetto globale per JavaScript, come descritto nel capitoloHello
`. + - [Comment](https://dom.spec.whatwg.org/#interface-comment) -- the class for comments. They are not shown, but each comment becomes a member of DOM. + +- [Element](https://dom.spec.whatwg.org/#interface-element) -- is the base class for DOM elements. + + It provides element-level navigation like `nextElementSibling`, `children` and searching methods like `getElementsByTagName`, `querySelector`. + + A browser supports not only HTML, but also XML and SVG. So the `Element` class serves as a base for more specific classes: `SVGElement`, `XMLElement` (we don't need them here) and `HTMLElement`. + +- Finally, [HTMLElement](https://html.spec.whatwg.org/multipage/dom.html#htmlelement) is the basic class for all HTML elements. We'll work with it most of the time. + + It is inherited by concrete HTML elements: + - [HTMLInputElement](https://html.spec.whatwg.org/multipage/forms.html#htmlinputelement) -- the class for `` elements, + - [HTMLBodyElement](https://html.spec.whatwg.org/multipage/semantics.html#htmlbodyelement) -- the class for `` elements, + - [HTMLAnchorElement](https://html.spec.whatwg.org/multipage/semantics.html#htmlanchorelement) -- the class for `` elements, + - ...and so on. +>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9 In definitiva, la lista completa delle proprietà e dei metodi di un nodo è il risultato dell'ereditarietà. +<<<<<<< HEAD Consideriamo, ad esempio, l'oggetto DOM per un elemento `` che appartiene alla classe [HTMLInputElement](https://html.spec.whatwg.org/multipage/forms.html#htmlinputelement). +======= +So, the full set of properties and methods of a given node comes as the result of the chain of inheritance. +>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9 Esso riceve proprietà e metodi per effetto della sovrapposizione di (elencate in ordine di ereditarietà): @@ -132,11 +172,19 @@ Per esempio: ``` +<<<<<<< HEAD Ma ci sono eccezioni; ad esempio `input.value` si sincronizza solo da attributo a proprietà, ma non al contrario: +======= +But there are exclusions, for instance `input.value` synchronizes only from attribute -> property, but not back: +>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9 ```html run diff --git a/2-ui/1-document/07-modifying-document/5-why-aaa/task.md b/2-ui/1-document/07-modifying-document/5-why-aaa/task.md index 365a8ae47..5282b4e28 100644 --- a/2-ui/1-document/07-modifying-document/5-why-aaa/task.md +++ b/2-ui/1-document/07-modifying-document/5-why-aaa/task.md @@ -22,6 +22,10 @@ Perché? alert(table); // la tabella, come dovrebbe essere table.remove(); +<<<<<<< HEAD // perché aaa è ancora nel documento? +======= + // why there's still "aaa" in the document? +>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9 ``` diff --git a/2-ui/1-document/08-styles-and-classes/article.md b/2-ui/1-document/08-styles-and-classes/article.md index 185c72f89..32209737d 100644 --- a/2-ui/1-document/08-styles-and-classes/article.md +++ b/2-ui/1-document/08-styles-and-classes/article.md @@ -129,8 +129,21 @@ setTimeout(() => document.body.style.display = "", 1000); // ritorna alla normal Se assegniamo una stringa vuota a `style.display`, il browser applica come di consueto le classi CSS ed i suoi stili predefiniti, come se non ci fosse alcuna proprietà `style.display`. +<<<<<<< HEAD ````smart header="Riscrittura completa con `style.cssText`" Di solito usiamo `style.*` per assegnare le proprietà di stile individualmente. Non possiamo impostare tutti gli stili in questo modo `div.style="color: red; width: 100px"`, perché `div.style` è un oggetto ed è in sola lettura. +======= +Also there is a special method for that, `elem.style.removeProperty('style property')`. So, We can remove a property like this: + +```js run +document.body.style.background = 'red'; //set background to red + +setTimeout(() => document.body.style.removeProperty('background'), 1000); // remove background after 1 second +``` + +````smart header="Full rewrite with `style.cssText`" +Normally, we use `style.*` to assign individual style properties. We can't set the full style like `div.style="color: red; width: 100px"`, because `div.style` is an object, and it's read-only. +>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9 Per impostare tutti gli stili come stringa c'è una speciale proprietà `style.cssText`: @@ -261,6 +274,7 @@ Attualmente, quindi, `getComputedStyle` restituisce il valore resolved della pro ````warn header="`getComputedStyle` richiede il nome completo della proprietà" Dovremmo sempre chiedere l'esatta proprietà che si desidera, come `paddingLeft` o `marginTop` o `borderTopWidth`. Diversamente il risultato corretto non è garantito. +<<<<<<< HEAD Per esempio, se ci sono le proprietà `paddingLeft/paddingTop`, cosa otterremmo con `getComputedStyle(elem).padding`? Niente, o forse un valore "generato" a partire dai valori di padding noti? Non esiste una regola standard in questo caso. Ci sono altre incongruenze. Ad esempio, alcuni browser (Chrome) mostrano `10px` nel documento in basso, ed altri (Firefox) -- invece no: @@ -276,6 +290,9 @@ Ci sono altre incongruenze. Ad esempio, alcuni browser (Chrome) mostrano `10px` alert(style.margin); // Firefox restituisce una stringa vuota ``` +======= +For instance, if there are properties `paddingLeft/paddingTop`, then what should we get for `getComputedStyle(elem).padding`? Nothing, or maybe a "generated" value from known paddings? There's no standard rule here. +>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9 ```` ```smart header="Gli stili applicati ai link `:visited` sono nascosti!" diff --git a/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/field.svg b/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/field.svg index 4ae90b1c7..f5bd9f4f9 100644 --- a/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/field.svg +++ b/2-ui/1-document/09-size-and-scroll/4-put-ball-in-center/field.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/2-ui/1-document/09-size-and-scroll/article.md b/2-ui/1-document/09-size-and-scroll/article.md index ef666f254..6dbc338fa 100644 --- a/2-ui/1-document/09-size-and-scroll/article.md +++ b/2-ui/1-document/09-size-and-scroll/article.md @@ -17,8 +17,8 @@ Useremo l'elemento indicato sotto quale esempio di tali proprietà: width: 300px; height: 200px; border: 25px solid #E8C48F; - padding: 20px; - overflow: auto; + padding: 20px; + overflow: auto; } ``` @@ -106,7 +106,11 @@ Le proprietà geometriche sono calcolate solo per gli elementi visibili. Se un elemento (o uno dei suoi antenati) ha `display:none` o non è nel documento, allora tutte le proprietà geometriche valgono zero (o `null` per `offsetParent`). +<<<<<<< HEAD Per esempio, `offsetParent` vale `null`, e `offsetWidth`, `offsetHeight` sono `0` quando abbiamo creato un elemento, ma non lo abbiamo ancora inserito nel documento, o esso (o un suo antenato) ha `display:none`. +======= +For example, `offsetParent` is `null`, and `offsetWidth`, `offsetHeight` are `0` when we created an element, but haven't inserted it into the document yet, or it (or its ancestor) has `display:none`. +>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9 Possiamo servirci di questa particolarità per verificare se un elemento è nascosto, in questo modo: diff --git a/2-ui/1-document/09-size-and-scroll/metric-all.svg b/2-ui/1-document/09-size-and-scroll/metric-all.svg index a5dadb47f..20a59e18d 100644 --- a/2-ui/1-document/09-size-and-scroll/metric-all.svg +++ b/2-ui/1-document/09-size-and-scroll/metric-all.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/2-ui/1-document/09-size-and-scroll/metric-client-left-top-rtl.svg b/2-ui/1-document/09-size-and-scroll/metric-client-left-top-rtl.svg index dd9e17cf8..e8dd3d60a 100644 --- a/2-ui/1-document/09-size-and-scroll/metric-client-left-top-rtl.svg +++ b/2-ui/1-document/09-size-and-scroll/metric-client-left-top-rtl.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/2-ui/1-document/09-size-and-scroll/metric-client-left-top.svg b/2-ui/1-document/09-size-and-scroll/metric-client-left-top.svg index 968590466..8097afa78 100644 --- a/2-ui/1-document/09-size-and-scroll/metric-client-left-top.svg +++ b/2-ui/1-document/09-size-and-scroll/metric-client-left-top.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/2-ui/1-document/09-size-and-scroll/metric-client-width-height.svg b/2-ui/1-document/09-size-and-scroll/metric-client-width-height.svg index 83864b4c5..2603b05fb 100644 --- a/2-ui/1-document/09-size-and-scroll/metric-client-width-height.svg +++ b/2-ui/1-document/09-size-and-scroll/metric-client-width-height.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/2-ui/1-document/09-size-and-scroll/metric-css.svg b/2-ui/1-document/09-size-and-scroll/metric-css.svg index 13aa62afd..1f2e5f780 100644 --- a/2-ui/1-document/09-size-and-scroll/metric-css.svg +++ b/2-ui/1-document/09-size-and-scroll/metric-css.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/2-ui/1-document/09-size-and-scroll/metric-offset-parent.svg b/2-ui/1-document/09-size-and-scroll/metric-offset-parent.svg index 9e247639b..2d108473e 100644 --- a/2-ui/1-document/09-size-and-scroll/metric-offset-parent.svg +++ b/2-ui/1-document/09-size-and-scroll/metric-offset-parent.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/2-ui/1-document/09-size-and-scroll/metric-offset-width-height.svg b/2-ui/1-document/09-size-and-scroll/metric-offset-width-height.svg index 49bdccda7..4d30d90cc 100644 --- a/2-ui/1-document/09-size-and-scroll/metric-offset-width-height.svg +++ b/2-ui/1-document/09-size-and-scroll/metric-offset-width-height.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/2-ui/1-document/09-size-and-scroll/metric-scroll-top.svg b/2-ui/1-document/09-size-and-scroll/metric-scroll-top.svg index c6d14d0f3..7f72de422 100644 --- a/2-ui/1-document/09-size-and-scroll/metric-scroll-top.svg +++ b/2-ui/1-document/09-size-and-scroll/metric-scroll-top.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/2-ui/1-document/09-size-and-scroll/metric-scroll-width-height.svg b/2-ui/1-document/09-size-and-scroll/metric-scroll-width-height.svg index 0c3d29952..75a24e3bc 100644 --- a/2-ui/1-document/09-size-and-scroll/metric-scroll-width-height.svg +++ b/2-ui/1-document/09-size-and-scroll/metric-scroll-width-height.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/2-ui/1-document/10-size-and-scroll-window/document-client-width-height.svg b/2-ui/1-document/10-size-and-scroll-window/document-client-width-height.svg index 65e77ae80..18cd37a74 100644 --- a/2-ui/1-document/10-size-and-scroll-window/document-client-width-height.svg +++ b/2-ui/1-document/10-size-and-scroll-window/document-client-width-height.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/2-ui/1-document/11-coordinates/article.md b/2-ui/1-document/11-coordinates/article.md index 74b0ad434..3250eb8dd 100644 --- a/2-ui/1-document/11-coordinates/article.md +++ b/2-ui/1-document/11-coordinates/article.md @@ -36,7 +36,11 @@ Ci sono, inoltre, proprietà derivate: ```online Clicca, per esempio, su questo pulsante per conoscere le sue coordinate relative alla finestra: +<<<<<<< HEAD +======= + +>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9 ``` +<<<<<<< HEAD Come possiamo osservare, se `addEventListener` riceve un oggetto come gestore, allora chiama `obj.handleEvent(event)` nel caso ci sia un evento. +======= +As we can see, when `addEventListener` receives an object as the handler, it calls `obj.handleEvent(event)` in case of an event. + +We could also use objects of a custom class, like this: +>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9 Possiamo usare anche una classe: @@ -391,6 +424,7 @@ Possiamo usare anche una classe: *!* let menu = new Menu(); + elem.addEventListener('mousedown', menu); elem.addEventListener('mouseup', menu); */!* diff --git a/2-ui/2-events/02-bubbling-and-capturing/article.md b/2-ui/2-events/02-bubbling-and-capturing/article.md index 113e42ab7..0b25eac02 100644 --- a/2-ui/2-events/02-bubbling-and-capturing/article.md +++ b/2-ui/2-events/02-bubbling-and-capturing/article.md @@ -120,27 +120,46 @@ In genere non ci sono reali necessità di interrompere il *bubbling*. Un problem C'è un'altra fase nell'elaborazione degli eventi, chiamata "capturing". Viene usata raramente nel codice, ma talvolta può essere utile. +<<<<<<< HEAD Lo standard [DOM Events](http://www.w3.org/TR/DOM-Level-3-Events/) descrive 3 fasi nella propagazione dell'evento: +======= +The standard [DOM Events](https://www.w3.org/TR/DOM-Level-3-Events/) describes 3 phases of event propagation: +>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9 1. Fase capturing -- l'evento va sull'elemento. 2. Fase target -- l'evento ha raggiunto l'elemento target. 3. Fase bubbling -- l'evento risale su dall'elemento. +<<<<<<< HEAD Ecco la figura estratta dalle specifiche, di un click su un ``, la sequenza sarà:
+<<<<<<< HEAD
1. `HTML` -> `BODY` -> `FORM` -> `DIV` (fase di *capturing*, il primo listener):
2. `P` (fase target, viene innescata due volte, dato che abbiamo impostato due listener: *capturing* e *bubbling*)
3. `DIV` -> `FORM` -> `BODY` -> `HTML` (fase *bubbling*, il secondo listener).
+=======
+1. `HTML` -> `BODY` -> `FORM` -> `DIV -> P` (capturing phase, the first listener):
+2. `P` -> `DIV` -> `FORM` -> `BODY` -> `HTML` (bubbling phase, the second listener).
+
+Please note, the `P` shows up twice, because we've set two listeners: capturing and bubbling. The target triggers at the end of the first and at the beginning of the second phase.
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
La proprietà `event.eventPhase` restituisce il numero della fase in cui l'evento è stato catturato, ma viene usata raramente, dato che possiamo dedurla dal gestore.
@@ -190,8 +216,13 @@ La proprietà `event.eventPhase` restituisce il numero della fase in cui l'event
Se abbiamo assegnato l'evento con `addEventListener(..., true)`, allora siamo obbligati a fare menzione della stessa fase in `removeEventListener(..., true)` per rimuovere l'handler con successo.
```
+<<<<<<< HEAD
````smart header="A parità di elemento e fase, i listeners verranno eseguiti secondo l'ordine di assegnazione"
Nel caso in cui avessimo più gestori assegnati alla stessa fase, assegnati allo stesso evento, tramite `addEventListener`, verranno eseguiti secondo l'ordine di creazione:
+=======
+````smart header="Listeners on the same element and same phase run in their set order"
+If we have multiple event handlers on the same phase, assigned to the same element with `addEventListener`, they run in the same order as they are created:
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
```js
elem.addEventListener("click", e => alert(1)); // vi è garanzia che venga eseguito prima
@@ -199,6 +230,12 @@ elem.addEventListener("click", e => alert(2));
```
````
+```smart header="The `event.stopPropagation()` during the capturing also prevents the bubbling"
+The `event.stopPropagation()` method and its sibling `event.stopImmediatePropagation()` can also be called on the capturing phase. Then not only the futher capturing is stopped, but the bubbling as well.
+
+In other words, normally the event goes first down ("capturing") and then up ("bubbling"). But if `event.stopPropagation()` is called during the capturing phase, then the event travel stops, no bubbling will occur.
+```
+
## Riepilogo
@@ -216,7 +253,11 @@ Ogni handler accede alle proprietà dell'oggetto `event`:
Qualunque gestore può interrompere la propagazione dell'evento chiamando `event.stopPropagation()`, ma non è raccomandabile, in quanto non possiamo essere del tutto sicuri che non ne abbiamo bisogno ai livelli superiori, magari per questioni del tutto differenti.
+<<<<<<< HEAD
La fase di *capturing* viene usata molto raramente, solitamente gestiamo gli eventi nella fase di *bubbling*. Ed in questo c'è una logica.
+=======
+The capturing phase is used very rarely, usually we handle events on bubbling. And there's a logical explanation for that.
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
Nel mondo reale, quando avviene un incidente, prima intervengono le autorità locali. Loro conoscono meglio il posto dove è avvenuto. Quindi intervengono e autorità di alto livello in caso di necessità.
diff --git a/2-ui/2-events/02-bubbling-and-capturing/event-order-bubbling.svg b/2-ui/2-events/02-bubbling-and-capturing/event-order-bubbling.svg
index b62d99089..2ea88f081 100644
--- a/2-ui/2-events/02-bubbling-and-capturing/event-order-bubbling.svg
+++ b/2-ui/2-events/02-bubbling-and-capturing/event-order-bubbling.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/2-ui/2-events/03-event-delegation/article.md b/2-ui/2-events/03-event-delegation/article.md
index 9339c816a..c7e654423 100644
--- a/2-ui/2-events/03-event-delegation/article.md
+++ b/2-ui/2-events/03-event-delegation/article.md
@@ -1,7 +1,11 @@
# Event delegation
+<<<<<<< HEAD
Capturing e bubbling ci permettono di implementare uno dei pattern più potenti nella gestione degli eventi, e cioè *event delegation*.
+=======
+Capturing and bubbling allow us to implement one of the most powerful event handling patterns called *event delegation*.
+>>>>>>> 035c5267ba80fa7b55878f7213cbde449b4092d9
Il concetto di base è che se abbiamo una serie di elementi gestiti in maniera simile, allora, invece di assegnare un gestore per ognuno di essi, possiamo metterne uno solo sui loro antenati comuni.
diff --git a/2-ui/2-events/03-event-delegation/bagua-bubble.svg b/2-ui/2-events/03-event-delegation/bagua-bubble.svg
index c4cd1ee1e..4ae67102d 100644
--- a/2-ui/2-events/03-event-delegation/bagua-bubble.svg
+++ b/2-ui/2-events/03-event-delegation/bagua-bubble.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/2-ui/2-events/04-default-browser-action/article.md b/2-ui/2-events/04-default-browser-action/article.md
index e34cf5e66..6d86cc58b 100644
--- a/2-ui/2-events/04-default-browser-action/article.md
+++ b/2-ui/2-events/04-default-browser-action/article.md
@@ -17,7 +17,11 @@ Ci sono due modi per comunicare al browser che non vogliamo che esegua l'azione
- Il più comune è quello di usare il metodo `event.preventDefault()`, incluso nell'oggetto `event`.
- Se il gestore viene assegnato tramite `on Once upon a time there was a mother pig who had three little pigs. The three little pigs grew so big that their mother said to them, "You are too big to live here any longer. You must go and build houses for yourselves. But take care that the wolf does not catch you."
+ The three little pigs grew so big that their mother said to them, "You are too big to live here any longer. You must go and build houses for yourselves. But take care that the wolf does not catch you." The three little pigs set off. "We will take care that the wolf does not catch us," they said. Once upon a time there was a mother pig who had three little pigs. The three little pigs grew so big that their mother said to them, "You are too big to live here any longer. You must go and build houses for yourselves. But take care that the wolf does not catch you."
+ The three little pigs grew so big that their mother said to them, "You are too big to live here any longer. You must go and build houses for yourselves. But take care that the wolf does not catch you." The three little pigs set off. "We will take care that the wolf does not catch us," they said.