135 lines
3.5 KiB
Markdown
135 lines
3.5 KiB
Markdown
![]() |
---
|
||
|
id: 587d7b87367417b2b2512b40
|
||
|
title: Compare Scopes of the var and let Keywords
|
||
|
challengeType: 1
|
||
|
forumTopicId: 301195
|
||
|
dashedName: compare-scopes-of-the-var-and-let-keywords
|
||
|
---
|
||
|
|
||
|
# --description--
|
||
|
|
||
|
When you declare a variable with the `var` keyword, it is declared globally, or locally if declared inside a function.
|
||
|
|
||
|
The `let` keyword behaves similarly, but with some extra features. When you declare a variable with the `let` keyword inside a block, statement, or expression, its scope is limited to that block, statement, or expression.
|
||
|
|
||
|
For example:
|
||
|
|
||
|
```js
|
||
|
var numArray = [];
|
||
|
for (var i = 0; i < 3; i++) {
|
||
|
numArray.push(i);
|
||
|
}
|
||
|
console.log(numArray);
|
||
|
// returns [0, 1, 2]
|
||
|
console.log(i);
|
||
|
// returns 3
|
||
|
```
|
||
|
|
||
|
With the `var` keyword, `i` is declared globally. So when `i++` is executed, it updates the global variable. This code is similar to the following:
|
||
|
|
||
|
```js
|
||
|
var numArray = [];
|
||
|
var i;
|
||
|
for (i = 0; i < 3; i++) {
|
||
|
numArray.push(i);
|
||
|
}
|
||
|
console.log(numArray);
|
||
|
// returns [0, 1, 2]
|
||
|
console.log(i);
|
||
|
// returns 3
|
||
|
```
|
||
|
|
||
|
This behavior will cause problems if you were to create a function and store it for later use inside a for loop that uses the `i` variable. This is because the stored function will always refer to the value of the updated global `i` variable.
|
||
|
|
||
|
```js
|
||
|
var printNumTwo;
|
||
|
for (var i = 0; i < 3; i++) {
|
||
|
if (i === 2) {
|
||
|
printNumTwo = function() {
|
||
|
return i;
|
||
|
};
|
||
|
}
|
||
|
}
|
||
|
console.log(printNumTwo());
|
||
|
// returns 3
|
||
|
```
|
||
|
|
||
|
As you can see, `printNumTwo()` prints 3 and not 2. This is because the value assigned to `i` was updated and the `printNumTwo()` returns the global `i` and not the value `i` had when the function was created in the for loop. The `let` keyword does not follow this behavior:
|
||
|
|
||
|
```js
|
||
|
let printNumTwo;
|
||
|
for (let i = 0; i < 3; i++) {
|
||
|
if (i === 2) {
|
||
|
printNumTwo = function() {
|
||
|
return i;
|
||
|
};
|
||
|
}
|
||
|
}
|
||
|
console.log(printNumTwo());
|
||
|
// returns 2
|
||
|
console.log(i);
|
||
|
// returns "i is not defined"
|
||
|
```
|
||
|
|
||
|
`i` is not defined because it was not declared in the global scope. It is only declared within the for loop statement. `printNumTwo()` returned the correct value because three different `i` variables with unique values (0, 1, and 2) were created by the `let` keyword within the loop statement.
|
||
|
|
||
|
# --instructions--
|
||
|
|
||
|
Fix the code so that `i` declared in the if statement is a separate variable than `i` declared in the first line of the function. Be certain not to use the `var` keyword anywhere in your code.
|
||
|
|
||
|
This exercise is designed to illustrate the difference between how `var` and `let` keywords assign scope to the declared variable. When programming a function similar to the one used in this exercise, it is often better to use different variable names to avoid confusion.
|
||
|
|
||
|
# --hints--
|
||
|
|
||
|
`var` should not exist in code.
|
||
|
|
||
|
```js
|
||
|
(getUserInput) => assert(!getUserInput('index').match(/var/g));
|
||
|
```
|
||
|
|
||
|
The variable `i` declared in the if statement should equal "block scope".
|
||
|
|
||
|
```js
|
||
|
(getUserInput) =>
|
||
|
assert(
|
||
|
getUserInput('index').match(/(i\s*=\s*).*\s*.*\s*.*\1('|")block\s*scope\2/g)
|
||
|
);
|
||
|
```
|
||
|
|
||
|
`checkScope()` should return "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;
|
||
|
}
|
||
|
```
|