発端
Vue ファイルのscript タグ内、created に記載した関数のなかで、定義したはずの変数がコンソールで「定義されていません」というエラーになったのが、ことのおこり。
最初はキーワードを何も付けていなかった。
created() {
searchParams = new URLSearchParams(window.location.search);
if( searchParams.has('pattern') ){
pattern = searchParams.get('pattern');
if ( pattern === 'A' ) {
this.pattern = 'A';
} else if ( pattern === 'B' ) {
this.pattern = 'B';
}
}
}
で、当然のようにコンソールエラー。
※Vue ファイルコンパイル時は、エラーになりません。
Error in created hook: "ReferenceError: searchParams is not defined"
先のコードをこうすると、エラーは解消できる。
created() {
- searchParams = new URLSearchParams(window.location.search);
+ const searchParams = new URLSearchParams(window.location.search);
if( searchParams.has('pattern') ){
- pattern = searchParams.get('pattern');
+ const pattern = searchParams.get('pattern');
if ( pattern === 'A' ) {
this.testPattern[this.pattern] = 'A';
} else if ( pattern === 'B' ) {
this.testPattern[this.pattern] = 'B';
}
}
}
ところで、const
とvar
とlet
の違いって何なんだ。
1. 再代入の違い
const
は定数 constant、一度定義すると値を変更できない。
var
は変数 variable、値の再代入が可能。
let
が上2つと比べて異色だと感じたのだけど、そのまんま「~しましょう (let us)」のlet で再代入はできるけど、再宣言はできない。
再代入
let pattern = 'A';
pattern = 'B'; // エラーにならない
再宣言
let pattern = 'A';
let pattern = 'B'; // エラーになる
一回「pattern はAとしましょう Let pattern as A」と言った後に、もっかい無かったことのように「pattern はBとしましょう」とは言わない、といったイメージなんだろうか。
2. スコープの違い
但しこれらはスコープ(代入が適用される範囲)に違いがあり、let
はブロックスコープなので、例えば以下のようにif 文の入れ子構造でlet
を二度使うことは可能。
if ( true ) {
let pattern = 'A';
console.log(pattern); // A
if ( true ) {
let pattern = 'B'; // !!!!!! ブロックが異なるのでここでエラーにならない(再宣言の扱いでない) !!!!!!
console.log(pattern); // B
}
// ブロックの外では最初のpattern が保たれている
console.log(pattern); // A
}
関数がスコープになるvar
では入れ子の中での代入が外側に影響する。
if( true ) {
var pattern = 'A';
console.log(pattern); // A
if ( true ) {
var pattern = 'B';
}
// 入れ子の内側での代入に影響される
console.log(pattern); // B
}
まとめ
Key | Assign | Scope |
---|---|---|
const | ブロック | |
var | 関数 | |
let | o再代入, x再宣言 | ブロック |
感想
今回は、再代入する用途のない値なので引き続きconst
を使おうと思いました。