Q1宣言したあとに値を入れ替える予定がない変数には、どの宣言を使いますか?
let と const — 再代入と再宣言の制御
JavaScript の変数宣言を const と let の使い分けから学びます。再代入と再宣言の可否、const に代入し直したときの TypeError、camelCase の命名ルールまで扱います。
注文の合計を計算するにも、ログイン中のユーザー名を画面に出すにも、値に名前を付けて何度も参照する必要があります。この名前が変数(値に付けた名前で、その名前を書けば同じ値を取り出せる)です。
JavaScript で変数を用意する方法は const と let の 2 つあり、どちらを選ぶかであとから値を入れ替えられるかどうかが決まります。
値に名前を付ける — const と let の使い分け
同じ値をコードのあちこちに直接書くと、変えたくなったときに全部を探して直すことになります。単価や税率のような値には先に名前を付けておき、以降はその名前で参照します。
名前を付ける行を宣言(変数の名前を作り、最初の値を入れる行)と呼びます。
JavaScript の宣言は、名前を作ると同時に「この名前の中身をあとで入れ替えるか」も決めます。入れ替えないなら const、入れ替えるなら let です。
同じ名前に別の値を入れ直すことを再代入(宣言済みの名前へ、あとから別の値を入れること)、同じ名前をもう一度宣言することを再宣言(すでにある名前で、もう一度 const や let の宣言を書くこと)と呼びます。const で宣言した名前には再代入できないため、まず const で書き、入れ替えが必要になった行が出てきたときだけ let に変える進め方が扱いやすくなります。
| 宣言の種類 | 再代入 | 再宣言 |
|---|---|---|
| const | できない(TypeError) | できない(SyntaxError) |
| let | できる | できない(SyntaxError) |
TypeError と SyntaxError が何かは次の章で扱います。
const — 入れ替えない値に使う宣言
const は宣言した行で値を決め、その名前には以降別の値を入れません。商品名・単価・税率のように、処理の途中で変わらない値がこれにあたり、プログラムのほとんどの値はこちらで足ります。
なお "保温マグカップ" のように引用符で囲んだ文字の並びを文字列、1200 のような数を数値と呼びます。それぞれの詳しい扱い方は第 3 回と第 4 回で扱います。
次のコード例に出てくる console.log は、丸括弧に渡した値を結果の画面へ文字として出す命令です。本サイトのコンソールは画面を持たないので、確かめたい値はこれに渡して表示します。
// から行末まではコメント(実行されずに残る説明用の文字)で、結果には出ません。演習で最初から書かれている // ① のような行も、この形の説明です。
// 入れ替えない値は const
const productName = "保温マグカップ";
const unitPrice = 1200;
console.log(productName); // 保温マグカップ
console.log(unitPrice); // 1200
let — あとで値を入れ替える変数
在庫数や合計金額のように、処理を進めるうちに中身が変わる値には let を使います。= の右側ではそのときの値をそのまま読めるので、今の値を読んで計算し、その結果を同じ名前に入れ直す書き方ができます。
let orderTotal = 0;
orderTotal = orderTotal + 1200; // 今の値 0 に 1200 を足して入れ直す
orderTotal = orderTotal + 400; // 今の値 1200 に 400 を足して入れ直す
console.log(orderTotal); // 1600
再代入と再宣言 — 実行が止まる 2 つのエラー
const を選ぶ意味は、この名前の中身は最後まで変わらない、とコードの上で決めてしまうところにあります。
決めたあとで別の値を代入すると、JavaScript はその行で実行を止め、TypeError(値の扱い方が誤っているときに出るエラー)を出します。以降の行は動きません。
const の 1 本の流れ、下 1 行が let の流れ。const は代入した行で止まり、let はそのまま次へ進む。もう 1 つ止まる書き方が再宣言(すでに使っている名前を、同じ範囲でもう一度宣言すること)です。const でも let でも再宣言はできず、SyntaxError(コードの書き方そのものが文法に合っていないときに出るエラー)です。
名前の付け間違いや、同じ名前を別の用途で使い回した書き方に、その場で気付けます。
let cartQuantity = 1;
let cartQuantity = 2;
// SyntaxError: Identifier 'cartQuantity' has already been declared
入れ替えたいだけなら、宣言は最初の 1 回だけ書き、2 回目以降は名前に値を代入します。宣言のキーワードを書かない行は再代入なので、let であれば止まりません。
let itemQuantity = 1;
itemQuantity = 2; // 宣言せずに代入するので再代入
console.log(itemQuantity); // 2
エラーが出るタイミングが違います
再代入の TypeError は実行が進んだ末に、その行で出るため、そこまでの行の表示は残ります。
一方、再宣言の SyntaxError はコードを読み込む段階で出るため、1 行目から何も実行されません。表示が 1 つも出ていないときは、文法の誤りを先に疑います。
変数名の付け方 — camelCase と使える文字
変数名は、その値が何なのかを読み手に説明する場所です。a や data のような名前だと、離れた行を読むたびに宣言まで戻ることになります。unitPrice や stockCount のように、中身がそのまま読み取れる名前を付けます。
名前には英字・数字・アンダースコア・ドル記号が使え、先頭に数字は置けません。大文字と小文字は区別され、stockcount と stockCount は別の変数です。
const / let / if のように JavaScript が意味を決めている語(予約語)は名前にできません。
| 変数名 | 使える / 使えない | 理由 |
|---|---|---|
| stockCount | 使える | 英字だけの組み合わせ |
| item2Price | 使える | 先頭が英字なら途中に数字を含められる |
| _draftOrder | 使える | アンダースコア始まりも許される |
| $price | 使える | ドル記号も名前に使える |
| 2ndItem | 使えない | 先頭に数字は置けない |
| item-price | 使えない | ハイフンは引き算と区別が付かない |
| const | 使えない | 予約語は名前にできない |
単語が 2 つ以上つながる名前は、camelCase(先頭の単語は小文字で始め、2 語目以降の先頭だけ大文字にする書き方)で書きます。priceWithTax や orderTotal のような形です。
JavaScript の標準の関数やプロパティもこの形なので、揃えておくと自作の名前だけが浮きません。
const listPrice = 1250;
const discountRate = 0.15; // 会員割引 15%
// 名前を見れば何の金額かが分かる
const discountedPrice = listPrice * (1 - discountRate);
console.log(discountedPrice); // 1062.5
// 円未満は切り捨てる
console.log(Math.floor(discountedPrice)); // 1062
var を使わない理由
古いコードや古い解説記事には、3 つ目の宣言として var が出てきます。var は同じ名前で何度でも再宣言でき、宣言より前の行で参照してもエラーにならず、値が入っていない状態のまま処理が進みます。名前が有効になる範囲も const / let とは違います。
誤りをその場で知らせてくれないので、原因が見つかるのが遅くなります。
新しく書くコードでは var を使いません
const と let は、再宣言も宣言前の参照もエラーとして知らせます。本講座でも以降 var は使いません。有効範囲そのものの詳しい仕組みは、文法カテゴリのスコープの記事で扱います。
この記事では、値に名前を付ける const と let の使い分け、const への再代入で出る TypeError と再宣言で出る SyntaxError、そして camelCase を含む命名のルールを扱いました。入れ替えない値は const、入れ替える値だけ let という選び方は、このあとのすべてのコードで使います。
理解度チェック
まずは1問ずつ答えてみましょう。
Q2次のコードを実行するとどうなりますか?const unitPrice = 1200;
unitPrice = 1500;
console.log(unitPrice);
Q3次のうち、変数名として使えないものはどれですか?