ホームページ  >  記事  >  ウェブフロントエンド  >  JS における「一時的なデッドゾーン」の概念の詳細な紹介

JS における「一時的なデッドゾーン」の概念の詳細な紹介

php是最好的语言
php是最好的语言オリジナル
2018-08-08 10:09:337623ブラウズ

一時的なデッドゾーン

let コマンドがブロックレベルのスコープに存在する限り、宣言された変数はこの領域に「バインド」され、外部の影響を受けなくなります。 。 let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。

var tmp = 123;

if (true) {
  tmp = 'abc'; // ReferenceError
  let tmp;
}

上面代码中,存在全局变量tmp,但是块级作用域内let又声明了一个局部变量tmp,导致后者绑定这个块级作用域,所以在let声明变量前,对tmp赋值会报错。

ES6 明确规定,如果区块中存在letconst命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。

总之,在代码块内,使用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 规定暂时性死区和letconstrrreee

上記のコードにはグローバル変数 tmp がありますが、 let はブロックレベルのスコープでローカル変数 tmp を宣言しています。このブロックレベルのスコープはバインドされているため、let が変数を宣言する前に tmp に値を代入すると、エラーが報告されます。

ES6 では、ブロック内に let および const コマンドがある場合、このブロック内のこれらのコマンドによって宣言された変数は最初から閉じられたスコープを形成することを明確に規定しています。宣言前にこれらの変数を使用すると、エラーが発生します。

つまり、コード ブロック内では、let コマンドを使用して宣言されるまで変数は使用できません。文法的には、これは「一時的なデッド ゾーン」(TDZ) と呼ばれます。

rrreee上記のコードでは、let コマンドが変数 tmp を宣言する前に、変数 tmp の「デッド ゾーン」に属しています。 。

「一時的なデッド ゾーン」は、typeof が 100% 安全な操作ではなくなったことも意味します。

rrreee上記のコードでは、変数 xlet コマンドを使用して宣言されているため、宣言される前は の「デッド ゾーン」に属しています。 x。この変数を使用するとエラーが報告されます。したがって、typeof が実行されると、ReferenceError がスローされます。

比較のために、変数がまったく宣言されていない場合、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 サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。