3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【JavaScript】変数宣言 var / let / const の違いを理解する

Last updated at Posted at 2022-01-26

JavaScriptの変数宣言

  • varletconstの3つの宣言方法がある
  • varはJavaScriptリリース当初からある宣言方法
  • letconstはJavaScriptの最新標準仕様に採択されたES2015で追加された宣言方法
  • 3つの違いは 再宣言の可否再代入の可否スコープホイスティング の4点

3つの変数宣言の違い(結論)

var let const
再宣言 × ×
再代入 ×
スコープ 関数 ブロック ブロック
ホイスティング undefined エラー

先に結論を提示してしまうと上表の通りです。
ここからは実際にコードを書いて挙動の違いを確認していきます。

再宣言

再宣言:一度宣言した変数を再度宣言すること。

/* var */
var sushi = 'maguro';
console.log(sushi) // => maguro
var sushi = 'ikura';
console.log(sushi) // => ikura

/* let */ 
let sushi = 'maguro';
console.log(sushi) // => maguro
let sushi = 'ikura'; // Uncaught SyntaxError: Identifier 'sushi' has already been declared

/* const */
const sushi = 'maguro';
console.log(sushi) // => maguro
const sushi = 'ikura'; // Uncaught SyntaxError: Identifier 'sushi' has already been declared
  • varは再宣言が可能
  • letconstは再宣言の時点でエラー

再代入

再代入:既に値が入っている変数に再度値を代入すること。

/* var */
var sushi = 'maguro';
console.log(sushi) // => maguro
sushi = 'ikura';
console.log(sushi) // => ikura

/* let */ 
let sushi = 'maguro';
console.log(sushi) // => maguro
sushi = 'ikura';
console.log(sushi) // => ikura

/* const */
const sushi = 'maguro';
console.log(sushi) // => maguro
sushi = 'ikura'; // Uncaught TypeError: Assignment to constant variable.
  • varletは再代入が可能
  • constは再代入の時点でエラー

スコープ

スコープ:直訳すると scope:範囲 のことで、「変数のスコープ」とは「変数が使用出来る範囲」のことを指す。JavaScriptのスコープにはグローバルスコープローカルスコープの2種があり、ローカルスコープには関数スコープブロックスコープの2種がある。(詳細は割愛)

/* var */
var sushi = 'maguro';
if (true) {
    console.log(sushi); // => maguro
    var sushi = 'ikura';
    console.log(sushi); // => ikura
}
console.log(sushi); // => ikura

/* let */
let sushi = 'maguro';
if (true) {
    console.log(sushi); // => maguro
    let sushi = 'ikura';
    console.log(sushi); // => ikura
}
console.log(sushi); // => maguro

/* const */
const sushi = 'maguro';
if (true) {
    console.log(sushi); // => maguro
    const sushi = 'ikura';
    console.log(sushi); // => ikura
}
console.log(sushi); // => maguro
  • varは関数スコープなので、ブロック外で宣言された変数に対してブロック内で再宣言が出来てしまう。
  • letconstはブロックスコープなので、ブロックの内外で変数宣言は区別される。

ホイスティング

ホイスティング:コンテキスト内で宣言した変数定義をコード実行前にメモリに配置すること。巻き上げともいう。

/* var */
sushi = 'maguro';
console.log(sushi) // => maguro
var sushi;
console.log(sushi) // => maguro

/* let */
sushi = 'maguro';
console.log(sushi) // => maguro
let sushi;
console.log(sushi) // undefined

/* const */
sushi = 'maguro';
console.log(sushi) // => maguro
const sushi; // Uncaught SyntaxError: Missing initializer in const declaration 
  • varは変数宣言をする前に変数に入れた値がそのまま変数宣言時の値に引き継がれている。
  • letundefined、つまり「変数宣言はされているけど値が定義されていませんよ」の状態。
  • constは変数宣言時に値の定義も必要なので、「値が定義されていませんよ」の状態。

まとめ

  • varはミスリーディングによる意図せぬ変数使用が起こり得るので使うべきではない
  • 変数宣言は大人しくconstを使おう
  • 再代入が必要な場合に限りletを使おう

(以前の案件のソースコードは全ての変数がvarで宣言されていたけど、良い「悪い例」だったなあ、と…。)

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?