varとlet、constの使い方を理解する前に、いくつかの概念を知っておくことが重要です:
スコープ
1.グローバル・スコープ:ウィンドウ、一般に次のように定義されます。
<script>
// code
</script>
2.関数スコープ:関数によってラップされたコードブロック
function test() {
//code
}
3.ブロック・レベル・スコープ: { }の ペアで定義されるステートメントをブロック・ステートメントと呼びます。
if(){}: はブロックである。
for(){}: はブロックである。
一時的なデッドゾーン
letコマンドがブロックレベルのスコープに存在する限り、宣言した変数はその領域に「バインド」され、外部からの影響を受けなくなります。
letコマンドを使ってコードブロック内で変数を宣言すると、その変数は使用できなくなります。これは構文上、「一時的なデッドゾーン」として知られています。
一時的デッドゾーンの本質は、現在のスコープに入った時点で、使いたい変数はすでに存在しているがアクセスできず、その変数を宣言したコード行が現れて初めてアクセスして使えるようになる、というものです。
var tmp = 123; // グローバル変数
if (true) {
tmp = 'abc'; // ReferenceError
let tmp; // ブロック・レベル・スコープの内部で、letは別のローカル変数tmpを宣言する。
}
//グローバル変数tmpは存在するが、letはブロックレベルのスコープで別のローカル変数tmpを宣言する。
//そのため、letが変数を宣言する前にtmpに値を代入するとエラーになる。
ES6では、ブロック内にletコマンドとconstコマンドがある場合、このブロックはこれらのコマンドで宣言された変数に対して最初から閉じたスコープを形成すると明示されています。宣言されている間にこれらの変数を使用すると、エラーが報告されます。
I. スコープの違い
**var で宣言された変数にはブロックレベルのスコープはありません。
**
var x = 1;
{
var x = 2;
}
console.log(x);
//ブロック内のvar文は、ブロックの前のvar文と同じスコープを持つため、2が出力される。
//CやJavaでは、このコードは1を出力する。
//このコードは、varがブロック・スコープを持たないことを証明している。
2. letと constを 使用して宣言された変数は、ブロックスコープされます。
let x = 1;
{
let x = 2;
}
console.log(x);
// 出力1
// xブロックレベルのスコープに限定される
// ここでは、letをconstに置き換えても同じ結果になる。
3, ブロックレベルのスコープを持つ関数
foo('outside'); // TypeError: foo is not a function
{
function foo(location) {
console.log('foo is called ' + location);
}
foo('inside'); // 定数の動作と表示'foo is called inside'
}
5.例
var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {console.log(i);};
}
a[0](); // 10
a[1](); // 10
a[6](); // 10
//variはグローバル変数として定義され、サイクルバッドは毎回同じiを指すので、最終的な出力は同じ値になる。
/********************/
var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function () {console.log(i);};
}
a[0](); // 0
a[1](); // 1
a[6](); // 6
//letiの定義はブロック・スコープであり、iの各ループは現在のループにのみ適用され、badの各サイクルは1回再定義される。
//for's()は親スコープである。,{}これはサブスコープである
可変リフティングの有無
1、定義:宣言内の変数を使用することができます、宣言のアクセスの結果、未定義で
2. var変数のリフティング、let 変数と const変数の一時的なデッドゾーン
console.log(a);
//エラー: VM194:1 Uncaught ReferenceError: a is not defined at <anonymous>:1:13let a = 1;
console.log(a);
//エラー:捕捉されない参照エラー(Uncaught ReferenceError: Cannot access 'c' before initializationat <anonymous>:1:13
const a = 1;
console.log(b); //undefined 変数リフティングの存在
var b = 1;
III.反復申告の可否
Letsとconstは同じスコープで同じ名前の変数を宣言できませんが、varはできます。
var a = 100;
console.log(a); // 100
var a = 10;
console.log(a); // 10
let a = 100;
let a = 10;
// コンソールエラー:識別子'a' has already been declared ===> 識別子aが宣言されている。
let b = 100
var b = 10;
// コンソールエラー:識別子'b' has already been declared ===> 識別子bが宣言された。
const c = 100;
var c = 10;
// コンソールエラー:識別子'b' has already been declared ===> 識別子bが宣言された。
//まとめると、letまたはvarで宣言された変数は、var、let、constで再び宣言することはできない。
const
1.一度宣言したら、必ず値を代入しなければならず、nullプレースホルダを使用することはできません。
2. const宣言は、宣言後に変更できない値への読み取り専用の参照を作成します。宣言が複合型データの場合、その属性は変更できます。
3.定数は、そのスコープ内の他の変数や関数と同じ名前を持つことはできません。
const foo;// エラー、定数には初期値が必要である。
const list = [];
console.log(list); //[]
const obj = {};
obj.name = 'apple';
obj.a = 10000;
console.log(obj); //{a:10000,name:'apple'}
list[0] = 10;
console.log(list); //[10]const obj = {a:100}; //error 定義の重複