0
0

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 3 years have passed since last update.

JavaScript var let constの違い

Last updated at Posted at 2021-03-15

JavaScriptでは変数を定義する際利用できるキーワードは三つあります。

  • var:全バージョン利用可能
  • const:ECMAScript 6以降から利用可能
  • let:ECMAScript 6以降から利用可能

※ECMAScript 6は2015年6月に公開 各バージョンの公開日はここから参照

var

var文は関数スコープまたはグローバルスコープの変数を宣言し、任意でそれをある値に初期化します。

var message;    //初期化していないため [undefined]という特殊な値が設定される
var message2 = "Hello World!";

function showMessage(){
   console.info(message3);
   var message3 = "ShowMessage";
}

function showMessage2(){
   var message4;
   console.info(message4);
   message4 = "ShowMessage2";
}
showMessage();   //「undifined」が出力される
showMessage2();   //「undifined」が出力される
console.info(message);    //宣言して、値を設定されていないから「undifined」が出力される
console.info(message2);  //「Hello World!」が出力される
console.info(message3);  // 宣言されていないため、例外になる
console.info(message4);  // 宣言されていないため、例外になる

ちなみにvarなしで変数を宣言したら、グローバル変数になります

function show(){
    message = "global var";
}
show();
console.info(message);   //[global var]が出力される

※だがこのような変数宣言はお勧めしない、厳格モードの場合、エラーになります。

'use strict';
function show(){
    message = "global var";  //未定義のエラー
}
show();
console.info(message);   

巻き上げ(hoisting)

varでは同じスコープで同じ変数を複数回宣言してもエラーにはならない、かつ変数に新たな値をセットしない限り値も変わることはない。そしてスコープ内では宣言より前から利用可能です。これが出来る原因は巻き上げにあります。

巻き上げありのコード
console.log(hoisting);  //undefined
var hoisting;
console.log(hoisting);  //undefined
hoisting = 1;
console.log(hoisting);  //1
var hoisting;
console.log(hoisting);  //1
hoisting = 2;
console.log(hoisting);  //2

巻き上げの際は変数の宣言をグローバル又は関数の先頭に移動したように見える。

巻き上げの内部から見ると
var hoisting;
var hoisting;

console.log(hoisting);  //undefined

console.log(hoisting);  //undefined
hoisting = 1;
console.log(hoisting);  //1

console.log(hoisting);  //1
hoisting = 2;
console.log(hoisting);  //2

気づいてないかもしれないが、関数にも巻き上げされるんです。以下のようなコードに見覚えがあると思います。

巻き上げ前
show();  //関数が定義される前から呼び出しが出来ます
function show(){
  console.log("show message");
}
巻き上げ後
function show(){
  console.log("show message");
}
show();

var tst = function(){};
var tst2 => ()

関数の巻き上げが変数より優先されます。

関数の巻き上げが優先
console.log(typeof show);  // function
console.log(typeof tst1);  // undefined
console.log(typeof tst2);  // undefined
var show;
//宣言式の関数の巻き上げする
function show(){
  console.log("show message");
}
var tst1 = function(){};  //関数式は巻き上げされない
var tst2 = ()=>{};  //アロー関数も巻き上げされない

let

letで宣言した変数のスコープはブロックスコープです。ブロックスコープは一番近い{}で決めるので、if、while、fuction、及び単なる{}でもlet変数のスコープになります。

if(true){
  let a;
}
console.log(a); //ReferenceError: aが定義されていません

while(true){
  let b;
  break;
}
console.log(b); //ReferenceError: bが定義されていません

(function tst(){
  let c;
})();
console.log(c); //ReferenceError: cが定義されていません   varで宣言しても同じエラーになります

{
  let d;
}
console.log(d);//ReferenceError: dが定義されていません

letはvarのように同じスコープで同じ変数を複数回宣言することはできません。

var a;
var a;

{
 let b;
 let b;  //SyntaxError: b は既に宣言されている
}

letの動きはループ変数に非常に似合っている、varだとループがループの外部に漏れてしまうため。

for(var i=0;i<10;i++){}
console.log(i); // 10

for(let j=0;j<10;j++){}
console.log(j); // ReferenceError: jが定義されていません

厳密に言うとletで宣言した変数でも巻き上げされるのですが、一時的なデッドゾーン(temporal dead zone)によって変数が宣言される前に利用すると一律エラーになる。

const

constはletと基本的に同じ、正しいconstでは宣言と同時に初期化しなければならない、しかも初期化した後は変更不可

const message1; //例外
const message2 = "hello";
message2 = "hello2";//例外

const変数のパフォーマンスがvarとletより良いので、可能な場合はなるべくconstを使うように。

グローバル宣言

var firstName="first";
function tst(){
 lastName = "last";
}
tst();
console.info(window.firstName);//first
console.info(window.lastName );//last

let age=20;
console.info(window.age);//[undifined]が出力される

letで宣言したグローバル変数はvarのようにwindowのプロパティにはならない。

思考

for(var i=0;i<5;i++){
  setTimeout(()=>console.info(i),0);
}
for(var j=0;j<5;j++){
  setTimeout((m)=>console.info(m),0,j);
}
for(let k=0;k<5;k++){
  setTimeout(()=>console.info(k),0);
}
上記の三つのforループのそれぞれの出力結果と原因を考えてください 1.「5,5,5,5,5」 2.「0,1,2,3,4」 3.「0,1,2,3,4」
0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?