【Compare Scopes of the var and let Keywords】フリーコードキャンプを日本語で解説!

フリーコードキャンプ

おいーす、もりたけです。

フリーコードキャンプを日本語で解説!の第111弾です。

JavaScript Algorithms and Data Structures Certification (300 hours)の中の、

Introduction to the ES6 Challengesの中の、

Compare Scopes of the var and let Keywords

です。

さっそく見ていきましょう。

まずは本文から。

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:

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:

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.

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:

‘use strict’;
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.

 


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.

 

解説していきます。

今回はvarとletのスコープの違いについてです。

スコープとは範囲のようなものです。varとletでは変数として有効な範囲(スコープ)が違います。

varを使って変数を宣言するとグローバルにその変数が定義されます。関数のなかで使えばその関数の中(ローカル)で定義されます。

一方、letを使って変数を宣言すると、ブロックや式の中で宣言された場合はそのブロックや式の中でのみ定義されます。

例を見てみましょう。

var numArray = [];
for (var i = 0; i < 3; i++) {
  numArray.push(i);
}
console.log(numArray);
// returns [0, 1, 2]
console.log(i);
// returns 3
このコードではvarを使っているのでiはグローバルに宣言されています。つまり以下のコードと同じようなものです。
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
このようなコードを書いてしまうと後で変数iを使ったforループなどを書いてしまうと問題が発生してしまいます。
例えば以下のようなコードを続けて書いたとします。
var printNumTwo;
for (var i = 0; i < 3; i++) {
  if (i === 2) {
    printNumTwo = function() {
      return i;
    };
  }
}
console.log(printNumTwo());
// returns 3
このコードでは関数printNumTwoがforループで生成されたiではなく、グローバルのiを返してしまうためconsole.log(printNumTwo());の結果が3になります。
letを使うとこのような事は起こりません。
‘use strict’;
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がグローバル変数として宣言されていないので、”i is not defined”と返ってきます。
また、forループの処理の中で使われたiは正しく処理され、console.log(printNumTwo());は2をかえします。
では課題を見てみましょう。
if文の中で使われているiが関数の中で宣言されているiとは別物になるようにしろ。
また、varはどこにも使ってはいけない。という課題です。
この課題ではvarとletのスコープの違いを理解することを目的としています。実際には同じ変数を何度も使うのは混乱する事があるので推奨されていません。
宣言の仕方をvarからletに変えてあげればいいだけですね。
答えはこうです。
function checkScope() {
  ‘use strict’;
  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;
}
という事で今回はvarとletのスコープの違いを学びました。
では次回!
タイトルとURLをコピーしました