Skip to content

Logical operators #181

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 24 commits into from
Jan 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
e8e2276
Update article.md
Dorin-David Jan 21, 2021
b9df73b
Update article.md
Dorin-David Jan 21, 2021
f80fb36
Update article.md
Dorin-David Jan 22, 2021
a45abf0
Update task.md
Dorin-David Jan 22, 2021
fb58982
Update task.md
Dorin-David Jan 22, 2021
aff5e39
Update solution.md
Dorin-David Jan 22, 2021
f70d723
Update task.md
Dorin-David Jan 22, 2021
7f20acf
Update task.md
Dorin-David Jan 22, 2021
ba54fbf
Update solution.md
Dorin-David Jan 22, 2021
d5bafd0
Update task.md
Dorin-David Jan 22, 2021
3b38b4d
Update article.md
pasor1 Jan 22, 2021
4da1550
Merge pull request #2 from pasor1/patch-1
Dorin-David Jan 22, 2021
cf4680a
Update task.md
Dorin-David Jan 22, 2021
d9a93b9
Update task.md
Dorin-David Jan 22, 2021
698314b
Update task.md
Dorin-David Jan 22, 2021
27587d1
Update 1-js/02-first-steps/11-logical-operators/2-alert-or/solution.md
Dorin-David Jan 23, 2021
f92c0cb
Update 1-js/02-first-steps/11-logical-operators/article.md
Dorin-David Jan 23, 2021
1a39e5f
Update 1-js/02-first-steps/11-logical-operators/article.md
Dorin-David Jan 23, 2021
803368d
Update 1-js/02-first-steps/11-logical-operators/article.md
Dorin-David Jan 23, 2021
9930428
Update 1-js/02-first-steps/11-logical-operators/article.md
Dorin-David Jan 23, 2021
e2c97bd
Update 1-js/02-first-steps/11-logical-operators/article.md
Dorin-David Jan 23, 2021
b54fa5a
Update 1-js/02-first-steps/11-logical-operators/article.md
Dorin-David Jan 24, 2021
f25f2a6
Update task.md
Dorin-David Jan 24, 2021
c6a51aa
Update solution.md
Dorin-David Jan 24, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ importance: 5

---

# Qual'e il risultato dell'OR?
# Qual è il risultato dell'OR?

Che risultato restituirà il codice qui sotto?
Quale sarà il risultato del codice sotto?

```js
alert( null || 2 || undefined );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ La risposta: prima `1`, poi `2`.
alert( alert(1) || 2 || alert(3) );
```

La chiamata ad `alert` non ritorna alcun valore. In altre parole, ritorna `undefined`.
La chiamata ad `alert` non ritorna alcun valore; ossia `undefined`.

1. Il primo OR `||` valuta il suo operando sinistro `alert(1)`. Questo mostra il primo messaggio con `1`.
2. La funzione `alert` ritorna `undefined`, quindi OR prosegue con il secondo operando alla ricerca di un valore vero.
1. Il primo OR `||` valuta l'operando sinistro `alert(1)`. Questo mostra il primo messaggio, `1`.
2. La funzione `alert` ritorna `undefined`, quindi OR prosegue con il secondo operando, alla ricerca di un valore vero.
3. Il secondo operando `2` è vero; quindi l'esecuzione si ferma, viene ritornato `2` e mostrato dall'alert esterno.

Non ci sarà il `3`, perchè la valutazione non arriva a `alert(3)`.
4 changes: 2 additions & 2 deletions 1-js/02-first-steps/11-logical-operators/2-alert-or/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ importance: 3

---

# Qual'è il risultato dell'alert con l'OR?
# Qual è il risultato dell'alert con l'OR?

Cosa stampa il codice qui sotto?
Cosa mostrerà il codice sotto?

```js
alert( alert(1) || 2 || alert(3) );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ importance: 5

---

# Qual'è il risultato dell'AND?
# Qual è il risultato dell'AND?

Cosa mostrerà l'esecuzione di questo codice?

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ La risposta è: `1`, e poi `undefined`.
alert( alert(1) && alert(2) );
```

La chiamata `alert` ritorna `undefined` (mostra solo un messaggio, quindi non ha nessuna valore di ritorno significativo).
La chiamata `alert` ritorna `undefined` (mostra solo un messaggio, quindi non ha nessuna valore significativo di ritorno).

Per questo `&&` valuta l'operando di sinistra (che mostra `1`), e si ferma immediatamente, perchè `undefined` è un valore falso. AND `&&` cerca un valore falso e lo ritorna.
Per questo `&&`, valutato l'operando di sinistra (che mostra `1`), si ferma: `undefined` è un valore falso e `&&` lo ritorna immediatamente.

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ importance: 3

---

# Qual'è il risultato degli alert?
# Qual è il risultato degli alert?

Cosa mostrerà questo codice?

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ importance: 3

---

# Controlla l'intervallo esternamente
# Controlla l'intervallo fuori

Scrivi una condizione `if` che controlli la variabile `age`, questa NON deve essere compresa tra `14` e `90`, estremi inclusi.
Scrivi una condizione `if` che controlli la variabile `age`; questa NON deve essere compresa tra `14` e `90` (inclusi).

Scrivi due varianti: la prima utilizzando NOT `!`, la seconda -- senza.
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ La risposta: il primo e il terzo verranno eseguiti.
I dettagli:

```js run
// Runs.
// The result of -1 || 0 = -1, truthy
// Viene eseguito
// Il risultato di -1 || 0 = -1 è vero
if (-1 || 0) alert( 'first' );

// Doesn't run
// -1 && 0 = 0, falsy
// Non viene eseguito
// -1 && 0 = 0, falso
if (-1 && 0) alert( 'second' );

// Executes
// Operator && has a higher precedence than ||
// so -1 && 1 executes first, giving us the chain:
// Eseguito
// L'operatore && ha la precedenza su ||,
// quindi -1 && 1 vengono eseguiti per primi; la catena dentro `if` diventa:
// null || -1 && 1 -> null || 1 -> 1
if (null || -1 && 1) alert( 'third' );
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ importance: 5

---

# Una indovinello con "if"
# Un indovinello con "if"

Quali di questi `alert` verranno eseguiti?

Quale sarà il risultato dell'espressione all'interno di `if(...)`?
Quale sarà il risultato delle espressioni all'interno dei vari `if(...)`?

```js
if (-1 || 0) alert( 'first' );
Expand Down
14 changes: 7 additions & 7 deletions 1-js/02-first-steps/11-logical-operators/9-check-login/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,20 @@ importance: 3

Scrivi il codice che richiede un login tramite `prompt`.

Se l'utente digita `"Admin"`, allora si richiede una password tramite `prompt`, se l'input è una stringa vuota o `key:Esc` -- mostra "Canceled.", se invece è un'altra stringa -- allora mostra "I don't know you".
Se l'utente digita `"Admin"`, si richiede una password tramite `prompt`; se l'input è una stringa vuota o `key:Esc` -- mostra "Canceled."; se è diversa da `"Admin"`, mostra "I don't know you".

La passoword viene controllata con le seguenti regole:
La passoword viene controllata secondo i seguenti criteri:

- Se è uguale a "TheMaster", allora mostra "Welcome!",
- Un'altra stringa -- mostra "Wrong password",
- Per una stringa vuota o `key:Esc`, mostra "Canceled."
- Se è uguale a "TheMaster", mostra "Welcome!",
- Un stringa diversa da "TheMaster" -- mostra "Wrong password",
- Una stringa vuota o `key:Esc` -- mostra "Canceled."

Lo schema:

![](ifelse_task.svg)

Utilizzate blocchi `if` annidati. Tenete a mente anche la leggibilità del codice.
Utilizza blocchi `if` annidati e tieni a mente la leggibilità del codice.

Suggerimento: passare un input vuoto tramite prompt ritorna una stringa vuota `''`. Premere `key:ESC` con prompt aperto ritorna `null`.
Suggerimento: passare un input vuoto tramite prompt ritorna una stringa vuota `''`. Premere `key:ESC` metre il prompt è aperto ritorna `null`.

[demo]
81 changes: 36 additions & 45 deletions 1-js/02-first-steps/11-logical-operators/article.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Operatori logici

In JavaScript ci sono tre operatori logici: `||` (OR), `&&` (AND), `!` (NOT).
In JavaScript ci sono tre operatori logici: `||` (OR), `&&` (AND), e `!` (NOT).

Nonostante si chiamino "logici", possono essere applicati a valori di qualsiasi tipo, non solo ai booleani. Il risultato stesso può essere di qualunque tipo.
Nonostante si chiamino "logici", possono essere applicati a valori di qualsiasi tipo, non solo ai booleani (i risultati stessi possono essere di qualunque tipo).

Vediamoli nei dettagli.

Expand All @@ -14,9 +14,9 @@ L'operatore "OR" viene rappresentato da due linee verticali:
result = a || b;
```

Nella programmazione classica, l'OR logico è pensato per manipolare solo tipi booleani. Se almeno un argomento è `true`, allora il risultato sarà `true`, altrimenti sarà `false`.
Nella programmazione classica, l'OR logico è utilizzato per manipolare solo tipi booleani. Se almeno un argomento è `true`, allora il risultato sarà `true`, altrimenti sarà `false`.

In JavaScript questo operatore è un più potente. Ma prima guardiamo come si comporta con valori booleani.
In JavaScript questo operatore è un po' più potente. Ma prima vediamo come si comporta con i valori booleani.

Ci sono quattro combinazioni logiche possibili:

Expand All @@ -27,11 +27,11 @@ alert( true || false ); // true
alert( false || false ); // false
```

Come possiamo vedere, il risultato è sempre `true` tranne nei casi in cui entrambi gli operandi sono `false`.
Come possiamo vedere, il risultato è sempre `true`, tranne nei casi in cui entrambi gli operandi sono `false`.

Se un operando non è booleano, allora viene convertito in booleano per essere valutato.
Se un operando non è di tipo booleano, allora viene momentaneamente convertito per la valutazione.

Ad esempio, il numero `1` viene visto come `true`, il numero `0` -- come `false`:
Ad esempio, il numero `1` viene considerato come `true`, il numero `0` come `false`:

```js run
if (1 || 0) { // funziona proprio come ( true || false )
Expand Down Expand Up @@ -60,17 +60,17 @@ let hour = 12;
let isWeekend = true;

if (hour < 10 || hour > 18 || isWeekend) {
alert( 'The office is closed.' ); // è il fine settimana
alert( 'The office is closed.' ); // l'Ufficio è chiuso
}
```

## OR "||" trova il primo valore vero

La logica descritta sopra è ovvia. Adesso proviamo ad addentrarci in qualche caratteristica "extra" di JavaScript.

Si può estendere l'algoritmo come segue:
Si può estendere l'algoritmo come segue.

Dando molti valori tramite OR:
Dati svariati operandi:

```js
result = value1 || value2 || value3;
Expand All @@ -79,12 +79,12 @@ result = value1 || value2 || value3;
L'operatore OR `||` si comporta come segue:

- Valuta gli operandi da sinistra a destra.
- Ogni operando viene converito in booleano. Se il risultato è `true`, allora si ferma e ritorna il valore originale dell'operando.
- Se tutti gli altri operandi sono stati valutati (ad esempio tutti erano `false`), ritorna l'ultimo operando.
- Ogni operando viene convertito a booleano. Se il risultato è `true`, il logical OR si ferma e ritorna il valore originale dell'operando.
- Se tutti gli operandi sono stati valutati e nessuno è `true`, ritorna l'ultimo operando.

Un valore viene ritornato nella sua forma originale, non nella sua conversione booleana.

In altra parole, una catena di OR `"||"` ritorna il primo valore vero, se invece non ce ne sono ritorna l'ultimo valore trovato.
In altre parole, una catena di OR `"||"` ritorna il primo valore vero; se invece non ce ne sono ritorna l'ultimo valore.

Ad esempio:

Expand All @@ -97,13 +97,13 @@ alert( null || 0 || 1 ); // 1 (il primo valore true)
alert( undefined || null || 0 ); // 0 (tutti falsi, ritorna l'ultimo valore)
```

Questo ci porta ad alcuni utilizzi interessanti rispetto al "puro e classico OR booleano".boolean-only OR".
Questo ci permette alcuni utilizzi interessanti rispetto al "puro e classico OR booleano"boolean-only OR".

1. **Prelevare il primo valore vero da una lista di variabili o espressioni.**
1. **Trovare il primo valore vero in una lista di variabili o espressioni.**

Immaginiamo di avere diverse variabili, `firstName`, `lastName` e `nickName`, tutti opzionali (possono quindi essere undefined o avere valori falsi).
Immaginiamo di avere diverse variabili, `firstName`, `lastName` e `nickName`, tutte opzionali (possono quindi essere *undefined* o avere valori falsi).

Possiamo utilizzare OR `||` per selezionare quello che contiene il valore e mostrarlo (oppure mostrare `"Anonymous"` se nessun valore è settato):
Possiamo utilizzare OR `||` per selezionare quella che contiene un valore e mostrarlo (oppure mostrare `"Anonymous"` se nessua variabile è definita):

```js run
let firstName = "";
Expand All @@ -119,27 +119,17 @@ Questo ci porta ad alcuni utilizzi interessanti rispetto al "puro e classico OR

2. **Valutazione a Corto-Circuito.**

Gli operandi, oltre che valori, possono essere anche espressioni arbitrarie. OR valuta ed esegue i test da sinistra a destra. La valutazione si ferma al primo risultato vero, questo viene poi ritornato. Il processo è chiamato "valutazione a corto-circuito", perchè cerca di terminare il prima possibile partendo da sinistra verso destra.
Gli operandi, oltre che valori, possono essere anche espressioni arbitrarie. L'operatore OR esegue la valutazione da sinistra a destra e si ferma al primo risultato vero, il quale viene ritornato. Il processo è chiamato "valutazione a corto-circuito" perché cerca di concludersi il prima possibile, senza dover elaborare tutti gli operandi.

Questo si vede chiaramente quando il secondo argomento causerebbe side-effect. Come l'assegnazione di una variabile.

Se proviamo ad eseguire l'esempio che segue, `x` non verrà assegnata:

alert(x); // undefined, perché (x = 1) non viene valutato
```

Se invece il primo argomento è `false`, allora `||` prosegue e valuta il secondo, in questo caso l'assegnazione funziona:
Il logical OR è particolarmente utile quando il secondo argomento causerebbe un *side-effect* come l'assegnazione di una variabile o la chiamata a una funzione.
Nell'esempio che segue solo il secondo messaggio verrà mostrato.

```js run no-beautify
*!*true*/!* || alert("not printed");
*!*false*/!* || alert("printed");
```

Un'assegnazione è un caso semplice. Potrebbero essere coinvolti altri tipi di side-effect.

Quello che abbiamo visto, è un "modo breve di fare `if`". Il primo operando viene convertito a booleano e solo se è falso viene eseguito il secondo.

La maggior parte delle volte è meglio utilizzare un " `if` "regolare", per mantenere il codice leggibile, in alcuni casi però può risultare utile.
Nella prima linea l'operatore OR trova subito un valore vero e ferma immediatamente la valutazione, quindi *alert* non viene eseguito.
Si può utilizzare questa funzionalità per eseguire un commando nel caso in cui la prima parte della condizione sia falsa.

## && (AND)

Expand Down Expand Up @@ -178,9 +168,9 @@ if (1 && 0) { // valutato come true && false
```


## AND "&& trova il primo valore falso
## AND "&&" trova il primo valore falso

Fornire più valori AND:
Dati svariati operandi:

```js
result = value1 && value2 && value3;
Expand All @@ -189,12 +179,12 @@ result = value1 && value2 && value3;
L'operatore AND `&&` si comporta come segue:

- Valuta gli operandi da sinistra a destra.
- Ogni operando viene convertito in booleano. Se il risultato è `false`, si ferma e ritorna il valore originale dell'operando.
- Se tutti gli operandi precedenti sono stati valutati (ad esempio nel caso siano tutti veri) , ritorna l'ultimo operando.
- Ogni operando viene convertito a booleano. Se il risultato è `false`, si ferma e ritorna il valore originale dell'operando.
- Se tutti gli operandi precedenti sono stati valutati e nessuno è `false`, ritorna l'ultimo operando.

In altre parole, AND ritorna il primo valore falso se lo trova, altrimenti ritorna l'ultimo valore.
In altre parole, AND ritorna il primo valore falso, altrimenti ritorna l'ultimo valore.

Le regole sono molto simili a quelle dell'OR. La differenza è che AND ritorna il primo valore *falso* mentre OR ritorna il primo valore *VERO*.
Le regole sono molto simili a quelle dell'OR. La differenza è che AND ritorna il primo valore *falso* mentre OR ritorna il primo valore *vero*.

Esempi:

Expand All @@ -210,7 +200,7 @@ alert( null && 5 ); // null
alert( 0 && "no matter what" ); // 0
```

Possiamo anche passare diversi valori in una sola riga. Vediamo come viene ritornato il primo valore falso:
Possiamo anche passare diversi valori in una sola riga. Nota come il primo valore falso viene ritornato non appena raggiunto:

```js run
alert( 1 && 2 && null && 3 ); // null
Expand All @@ -225,7 +215,7 @@ alert( 1 && 2 && 3 ); // 3, l'ultimo
````smart header="Precedenza di AND `&&` è maggiore dell'OR `||`"
La precedenza dell'operatore AND `&&` è maggiore di quella dell'OR `||`.

Quindi il codice `a && b || c && d` esegue in maniera analoga all'espressione: `(a && b) || (c && d)`.
Quindi il codice `a && b || c && d` è analogo all'espressione: `(a && b) || (c && d)`.
````

````warn header="Non rimpiazzate `if` con `||` o `&&`"
Expand All @@ -242,7 +232,7 @@ let x = 1;

Le azioni nella parte destra di `&&` vengono eseguite solamente se la valutazione non si ferma prima. Cioè: solo se `(x > 0)` è vera.

Quindi sostanzialmente è analogo a:
Il codie sopra è sostanzialmente analogo a:

```js run
let x = 1;
Expand All @@ -253,6 +243,7 @@ if (x > 0) alert( 'Greater than zero!' );
La variante con `&&` sembra essere più corta. Ma l'istruzione `if` è più ovvia e tende ad essere più leggibile.

Quindi è consigliato usare ogni costrutto solo per i suoi scopi. Usate un `if` se volete imporre una condizione. Utilizzate invece `&&` se volete un AND.
````

## ! (NOT)

Expand All @@ -266,7 +257,7 @@ result = !value;

L'operatore accetta un solo argomento e si comporta come segue:

1. Converte l'operando al tipo booleano: `true/false`.
1. Converte l'operando a booleano: `true/false`.
2. Ritorna il valore inverso.

Ad esempio:
Expand All @@ -283,13 +274,13 @@ alert( !!"non-empty string" ); // true
alert( !!null ); // false
```

Quello che accade è che il primo NOT converte il tipo a booleano e ritorna il suo inverso, il secondo NOT lo inverte nuovamente. Alla fine abbiamo un valore di tipo booleano.
Quello che accade è che il primo NOT converte l'operando a booleano e ritorna il suo inverso, e il secondo NOT lo *inverte nuovamente*. Il risultato è un valore di tipo booleano.

C'è un modo molto più lungo per fare la stessa cosa -- una funzione del linguaggio `Boolean`:
C'è un modo molto più lungo per fare la stessa cosa, usare la funzione `Boolean`, integrata in JavaScript:

```js run
alert( Boolean("non-empty string") ); // true
alert( Boolean(null) ); // false
```

La precedenza del NOT `!` è la più alta fra tutti gli operatori logici quindi viene sempre eseguita per prima, precede `&&`, `||`.
La precedenza del NOT `!` è la più alta fra tutti gli operatori logici; viene sempre eseguita per prima e precede sia `&&` che `||`.