はじめに
なんとなくJavaScriptを書き初めてしまっていたので、いまさらではあるのですが var, let , constの違いについて調べました。変数だし var(iable) だろと思い込んでいたのですが、使い分けがあるということがわかりました。
var, let, constとスコープ
以下のコードでテストしました。
console.log("global start"); // Break1
console.log(global_var);
var global_var = "1";
console.log(global_var);
console.log(global_let);
let global_let = "1";
console.log(global_let);
console.log(global_const);
const global_const = "1";
console.log(global_const);
console.log("global end"); // Break 2
browser.contextMenus.create({
id: "testVariable",
title: "test variable",
contexts: ["all"]
})
browser.contextMenus.onClicked.addListener((info, tab) => {
if (info.menuItemId === "testVariable") {
console.log("onClicked start"); // Break 3
console.log(global_var);
console.log(global_let);
console.log(global_const);
console.log(in_func_var);
console.log(in_func_let);
console.log(in_func_const);
testVariable();
console.log(global_var);
console.log(global_let);
console.log(global_const);
console.log(in_func_var);
console.log(in_func_let);
console.log(in_func_const);
console.log("onClicked end"); // Break 6
}
});
function testVariable() {
console.log("testVariable start"); // Break 4
console.log(in_func_var);
var in_func_var = "1";
console.log(in_func_var);
console.log(in_func_let);
let in_func_let = "1";
console.log(in_func_let);
console.log(in_func_const);
const in_func_const = "1";
console.log(in_func_const);
console.log("testVariable end"); // Break 5
};
global_const : uninitialized
global_let : uninitialized
global_var : undefined <<< 巻き上げ
global start background.js:31:1
undefined background.js:33:1
1 background.js:35:1
ReferenceError: can't access lexical declaration `global_let' before initialization
uninitilized の状態のものは Break 2 に至るまでにエラーになります。そのためエラーになる console.log はコメントにして実行
global_var : 1
global_let : 1
global_const : 1
Break 3
global_var : 1
global_let : 1
global_const : 1
in_func_* は var, let , const 共に見られない
onClicked start background.js:66:3
1 background.js:67:3
1 background.js:68:3
1 background.js:69:3
in_func_var is not defined
Break 4
global_var : 1
global_let : 1
global_const : 1
in_func_var : undefined
in_func_let : uninitialized
in_func_const : uninitialized
testVariable start background.js:113:2
undefined background.js:114:2
1 background.js:116:2
can't access lexical declaration `in_func_let' before initialization
Break 5
global_var : 1
global_let : 1
global_const : 1
in_func_var : 1
in_func_let : 1
in_func_const : 1
このあとで ここで in_func へのアクセスエラーが起きたので、コメントアウトしました。
Break6
スコープ - 使っている関数内のスコープ、グローバル、let,constであれば forループもスコープ
巻き上げ - 宣言前の同じスコープで undefined でアクセスできるか。uninitializedでアクセスできずにエラーになるか。
forループ
関数内のforループのスコープも確認しました。
function testVariable() {
console.log("testVariable start");
var in_func_var = "1";
let in_func_let = "1";
const in_func_const = "1";
for (let i=1;i<3; i++) {
console.log("for start");
var in_for_var = "1";
let in_for_let = "1";
const in_for_const = "1";
console.log("for ===");
in_for_var = "2";
in_for_let = "2";
in_for_const = "2";
console.log("for end");
}
console.log("testVariable end");
};
var は forループの中であっても 関数と同じスコープに見えます。
let , const は forループの中であれば、別のスコープでした。
let と const の代入
const は上のコードだと in_for_const = "2" のタイミングで次のエラーが出ます。
invalid assignment to const `in_for_const'
参考
文法とデータ型 - JavaScript | MDN
let - JavaScript | MDN
const - JavaScript | MDN