136 lines
4.0 KiB
Markdown
136 lines
4.0 KiB
Markdown
|
---
|
||
|
id: 587d7b87367417b2b2512b40
|
||
|
title: Confrontare gli ambiti di applicazione delle parole chiave var e let
|
||
|
challengeType: 1
|
||
|
forumTopicId: 301195
|
||
|
dashedName: compare-scopes-of-the-var-and-let-keywords
|
||
|
---
|
||
|
|
||
|
# --description--
|
||
|
|
||
|
Quando si dichiara una variabile con la parola chiave `var`, essa viene dichiarata globalmente, o localmente se dichiarata all'interno di una funzione.
|
||
|
|
||
|
La parola chiave `let` si comporta allo stesso modo, ma con alcune funzioni extra. Quando si dichiara una variabile con la parola chiave `let` all'interno di un blocco, di una dichiarazione o di un'espressione, il suo ambito di applicazione è limitato a tale blocco, dichiarazione o espressione.
|
||
|
|
||
|
Ad esempio:
|
||
|
|
||
|
```js
|
||
|
var numArray = [];
|
||
|
for (var i = 0; i < 3; i++) {
|
||
|
numArray.push(i);
|
||
|
}
|
||
|
console.log(numArray);
|
||
|
console.log(i);
|
||
|
```
|
||
|
|
||
|
Qui la console mostrerà i valori `[0, 1, 2]` e `3`.
|
||
|
|
||
|
Con la parola chiave `var`, `i` viene dichiarata globalmente. Quindi, quando `i++` viene eseguito, aggiorna la variabile globale. Questo codice è simile al seguente:
|
||
|
|
||
|
```js
|
||
|
var numArray = [];
|
||
|
var i;
|
||
|
for (i = 0; i < 3; i++) {
|
||
|
numArray.push(i);
|
||
|
}
|
||
|
console.log(numArray);
|
||
|
console.log(i);
|
||
|
```
|
||
|
|
||
|
Qui la console mostrerà i valori `[0, 1, 2]` e `3`.
|
||
|
|
||
|
Questo comportamento causerà problemi se dovessi creare una funzione e memorizzarla per un uso successivo all'interno di un ciclo `for` che utilizza la variabile `i`. Questo perché la funzione memorizzata si riferirà sempre al valore della variabile globale `i` aggiornata.
|
||
|
|
||
|
```js
|
||
|
var printNumTwo;
|
||
|
for (var i = 0; i < 3; i++) {
|
||
|
if (i === 2) {
|
||
|
printNumTwo = function() {
|
||
|
return i;
|
||
|
};
|
||
|
}
|
||
|
}
|
||
|
console.log(printNumTwo());
|
||
|
```
|
||
|
|
||
|
Qui la console mostrerà il valore `3`.
|
||
|
|
||
|
Come puoi vedere, `printNumTwo()` stampa 3 e non 2. Questo perché il valore assegnato a `i` è stato aggiornato e `printNumTwo()` restituisce la variabile globale `i` e non il valore `i` che aveva quando la funzione è stata creata nel ciclo. La parola chiave `let` non segue questo comportamento:
|
||
|
|
||
|
```js
|
||
|
let printNumTwo;
|
||
|
for (let i = 0; i < 3; i++) {
|
||
|
if (i === 2) {
|
||
|
printNumTwo = function() {
|
||
|
return i;
|
||
|
};
|
||
|
}
|
||
|
}
|
||
|
console.log(printNumTwo());
|
||
|
console.log(i);
|
||
|
```
|
||
|
|
||
|
Qui la console mostrerà il valore `2` e un l'errore `i is not defined` (i non è definita).
|
||
|
|
||
|
`i` non è definita perché non è stata dichiarata nell'ambito globale. È dichiarata solo all'interno della condizione del ciclo `for`. `printNumTwo()` ha restituito il valore corretto perché tre variabili `i` differenti con valori univoci (0, 1, e 2) sono state create dalla parola chiave `let` all'interno della dichiarazione del ciclo.
|
||
|
|
||
|
# --instructions--
|
||
|
|
||
|
Correggi il codice in modo che la variabile `i` dichiarata nella condizione dell'`if` sia una variabile separata dalla `i` dichiarata nella prima riga della funzione. Assicurati di non usare la parola chiave `var` in nessun punto del tuo codice.
|
||
|
|
||
|
Questo esercizio è progettato per illustrare la differenza tra il modo in cui le parole chiave `var` e `let` assegnano l'ambito alla variabile dichiarata. Quando si programma una funzione simile a quella utilizzata in questo esercizio, è spesso meglio usare nomi di variabili diversi per evitare confusione.
|
||
|
|
||
|
# --hints--
|
||
|
|
||
|
`var` non dovrebbe esistere nel codice.
|
||
|
|
||
|
```js
|
||
|
(getUserInput) => assert(!getUserInput('index').match(/var/g));
|
||
|
```
|
||
|
|
||
|
La variabile `i` dichiarata nella condizione dell'`if` dovrebbe essere uguale alla stringa `block scope`.
|
||
|
|
||
|
```js
|
||
|
(getUserInput) =>
|
||
|
assert(
|
||
|
getUserInput('index').match(/(i\s*=\s*).*\s*.*\s*.*\1('|")block\s*scope\2/g)
|
||
|
);
|
||
|
```
|
||
|
|
||
|
`checkScope()` dovrebbe restituire la stringa `function scope`
|
||
|
|
||
|
```js
|
||
|
assert(checkScope() === 'function scope');
|
||
|
```
|
||
|
|
||
|
# --seed--
|
||
|
|
||
|
## --seed-contents--
|
||
|
|
||
|
```js
|
||
|
function checkScope() {
|
||
|
var i = 'function scope';
|
||
|
if (true) {
|
||
|
i = 'block scope';
|
||
|
console.log('Block scope i is: ', i);
|
||
|
}
|
||
|
console.log('Function scope i is: ', i);
|
||
|
return i;
|
||
|
}
|
||
|
```
|
||
|
|
||
|
# --solutions--
|
||
|
|
||
|
```js
|
||
|
function checkScope() {
|
||
|
let i = 'function scope';
|
||
|
if (true) {
|
||
|
let i = 'block scope';
|
||
|
console.log('Block scope i is: ', i);
|
||
|
}
|
||
|
|
||
|
console.log('Function scope i is: ', i);
|
||
|
return i;
|
||
|
}
|
||
|
```
|