一時的なデッドゾーン
let
コマンドがブロックレベルのスコープに存在する限り、宣言された変数はこの領域に「バインド」され、外部の影響を受けなくなります。 。 let
命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。
var tmp = 123; if (true) { tmp = 'abc'; // ReferenceError let tmp; }
上面代码中,存在全局变量tmp
,但是块级作用域内let
又声明了一个局部变量tmp
,导致后者绑定这个块级作用域,所以在let
声明变量前,对tmp
赋值会报错。
ES6 明确规定,如果区块中存在let
和const
命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。
总之,在代码块内,使用let
命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。
if (true) { // TDZ开始 tmp = 'abc'; // ReferenceError console.log(tmp); // ReferenceError let tmp; // TDZ结束 console.log(tmp); // undefined tmp = 123; console.log(tmp); // 123 }
上面代码中,在let
命令声明变量tmp
之前,都属于变量tmp
的“死区”。
“暂时性死区”也意味着typeof
不再是一个百分之百安全的操作。
typeof x; // ReferenceError let x;
上面代码中,变量x
使用let
命令声明,所以在声明之前,都属于x
的“死区”,只要用到该变量就会报错。因此,typeof
运行时就会抛出一个ReferenceError
。
作为比较,如果一个变量根本没有被声明,使用typeof
反而不会报错。
typeof undeclared_variable // "undefined"
上面代码中,undeclared_variable
是一个不存在的变量名,结果返回“undefined”。所以,在没有let
之前,typeof
运算符是百分之百安全的,永远不会报错。现在这一点不成立了。这样的设计是为了让大家养成良好的编程习惯,变量一定要在声明之后使用,否则就报错。
有些“死区”比较隐蔽,不太容易发现。
function bar(x = y, y = 2) { return [x, y]; } bar(); // 报错
上面代码中,调用bar
函数之所以报错(某些实现可能不报错),是因为参数x
默认值等于另一个参数y
,而此时y
还没有声明,属于”死区“。如果y
的默认值是x
,就不会报错,因为此时x
已经声明了。
function bar(x = 2, y = x) { return [x, y]; } bar(); // [2, 2]
另外,下面的代码也会报错,与var
的行为不同。
// 不报错 var x = x; // 报错 let x = x; // ReferenceError: x is not defined
上面代码报错,也是因为暂时性死区。使用let
声明变量时,只要变量在还没有声明完成前使用,就会报错。上面这行就属于这个情况,在变量x
的声明语句还没有执行完成前,就去取x
的值,导致报错”x 未定义“。
ES6 规定暂时性死区和let
、const
rrreee
tmp
がありますが、 let
はブロックレベルのスコープでローカル変数 tmp
を宣言しています。このブロックレベルのスコープはバインドされているため、let
が変数を宣言する前に tmp
に値を代入すると、エラーが報告されます。 ES6 では、ブロック内に let
および const
コマンドがある場合、このブロック内のこれらのコマンドによって宣言された変数は最初から閉じられたスコープを形成することを明確に規定しています。宣言前にこれらの変数を使用すると、エラーが発生します。 つまり、コード ブロック内では、let
コマンドを使用して宣言されるまで変数は使用できません。文法的には、これは「一時的なデッド ゾーン」(TDZ) と呼ばれます。 rrreee上記のコードでは、let
コマンドが変数 tmp
を宣言する前に、変数 tmp
の「デッド ゾーン」に属しています。 。
typeof
が 100% 安全な操作ではなくなったことも意味します。 比較のために、変数がまったく宣言されていない場合、typeof
を使用してもエラーは報告されません。 🎜rrreee🎜 上記のコードでは、undeclared_variable
は存在しない変数名であり、結果は「未定義」になります。したがって、let
が存在する前は、typeof
演算子は 100% 安全であり、エラーを報告することはありませんでした。これはもはや真実ではありません。この設計は、誰もが良いプログラミング習慣を身につけられるようにするためのものです。変数は宣言後に使用する必要があります。そうしないと、エラーが報告されます。 🎜🎜一部の「デッドゾーン」は隠されており、見つけるのは簡単ではありません。 🎜rrreee🎜上記のコードで、bar
関数を呼び出すとエラーが報告される理由は (一部の実装ではエラーが報告されない場合があります)、パラメータ x
のデフォルト値が原因です。は別のパラメータ y
と等しく、y
はこの時点では宣言されていないため、「デッド ゾーン」に属します。 y
のデフォルト値が x
である場合、この時点では x
が宣言されているため、エラーは報告されません。 🎜rrreee🎜 さらに、次のコードでもエラーが報告されます。これは、var
の動作とは異なります。 🎜rrreee🎜 上記のコードによって報告されるエラーも、一時的なデッド ゾーンが原因です。 let
を使用して変数を宣言する場合、宣言が完了する前に変数が使用されている限り、エラーが報告されます。上の行は、変数 x
の宣言ステートメントが実行される前に、x
の値が取得され、「x が定義されていません」というエラーが発生します。 🎜🎜ES6 では、一時的なデッドゾーンと let
および const
ステートメントでは変数の昇格が発生しないと規定されています。これは主に実行時エラーを減らし、変数がその前に使用されるのを防ぐためです。と宣言されているため、予期しない動作が発生する可能性があります。このような間違いは ES5 ではよくあることですが、この規定が整備されたことで、それらを避けるのは簡単です。 🎜🎜 つまり、一時的なデッドゾーンの本質は、現在のスコープに入るとすぐに、使用したい変数がすでに存在しますが、その変数を取得して使用できるのは の行までだけであるということです。変数を宣言するコードが表示されます。 🎜🎜関連する推奨事項: 🎜🎜🎜 JS の事前解析とは何ですか?🎜🎜🎜🎜 JS 文字列のindexof と search の使用の違いは何ですか🎜🎜以上がJS における「一時的なデッドゾーン」の概念の詳細な紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。