まるノート

備忘録も兼ねて、様々なお役立ち情報をまとめています。

JavaScript基礎知識 ~var/let/constについて~

はじめに

JavaScript について学習したことをまとめてゆこうと思います。
本記事では変数宣言で用いる var、let、const について挙動の違いなどを整理しました。


変数の理解には JavaScript のスコープの知識が大きく関わってくるのですが、変数だけに焦点をあてて、必要最低限だと思う内容を整理しました。


変数の再宣言と値の再代入

変数の再宣言

let、const は再宣言が不可能です。

let a;
let a;  // エラー発生:Uncaught SyntaxError: Identifier 'a' has already been declared


const b = 0;
const b = 0; // エラー発生:Uncaught SyntaxError: Identifier 'b' has already been declared


var は再宣言が可能です。エラーは発生しません。

var c;
var c; 


値の再代入

let, var で宣言した変数は値を再代入できます。

let a = 1;
a = 2;
var a = 1;
a = 2;


const で再代入しようとするとエラーになります。

const a = 1;
a = 2; // エラー発生:Uncaught TypeError: Assignment to constant variable.


ここまでは簡単だと思います。 少しややこしいのがスコープによる挙動の違いです。


スコープによる挙動の違い

スコープについて

スコープには大きく次の3種類があります。
※他にもありますが、とりあえずこの3つをおさえておきましょう。

  • グローバルスコープ:コードのどこからでもアクセスできる。関数スコープやブロックスコープの外側の領域
  • 関数スコープ:function f() { … } の波括弧 { … } で囲まれた範囲
  • ブロックスコープ: { … } で囲われた範囲。for 文やif 文の中などです


同じ波括弧 { … } でも、関数スコープとブロックスコープで特性が異なるのでそれぞれ区別が必要です


スコープによる挙動の違い

グローバルスコープ

let、var、const ともにアクセス(参照)可能です。変数の宣言や値の再代入については上述した規則に従います。


関数スコープ

関数スコープ内で var, let, const 命令で宣言された変数は、関数の外部からはアクセスすることができません。

let、const でも同様のエラーが発生します。

つまり、function f() { … } の波括弧は一つの閉じたスコープが形成されるということです。

しかし注意点として、関数の外側で宣言した変数には対して関数の中からアクセスすることはできます。var でも const でも同様です。


ブロックスコープ

関数スコープと同じ { … } の領域ですが、ブロックスコープの場合、
var 命令で宣言した変数のスコープは無視されます。


var だと宣言したブロック以外の意図しないところで値が変わってしまうので、let や const を利用するのが望ましいです。


ホイスティングによる初期値の設定

最後に、ホイスティングと呼ばれる JavaScript の仕組みにおける各変数の違いに触れます。


ホイスティングとは
JavaScript の実行エンジンが変数や関数定義をメモリに配置することを指します。 let/const/var 命令で宣言された変数や function 命令で宣言された関数は、コード実行前には既にメモリに配置されています。


let または constで宣言した変数の場合、宣言の前に値を取得しようとすると、エラーが発生します。一応メモリに変数のための領域がとられているのですが、初期値はまだ設定されておらず結局はエラーになってしまいます。

console.log("aの値:" + a); // エラー発生
let a = 10; 


ところが、同じように var で宣言した場合は結果が違います。
var の場合はメモリに変数のための領域が取られ、JavaScript エンジンにより undefined が設定(初期化)されます。

console.log("aの値:" + a); // undefined になる
let a = 10; 


基本的に変数は利用する前に宣言しますが、ホイスティングという仕組み自体は知っておくと良いかと思います。


おわりに

以上、JavaScript基礎知識として変数についての知識でした。
確実に知識を定着されるために、実際に簡単なプログラム実行して挙動を確かめてみることをお勧めします。


また記事が長くなるので割愛しましたが、関数を宣言した場合も実は var と同じような性質になります。(関数スコープ内で宣言した関数にはアクセスできないが、ブロックスコープ内で宣言した関数には外から呼び出し可能)

ここらへんのことも気が向いたら掘り下げてゆこうと思います。