ホイスティングとは、実行前に宣言が行われる JavaScript のプロセスを指します。変数と関数の宣言が最初に処理されます。その結果、宣言前に変数が参照されてもエラーにはならず、unknown が返されます。関数宣言の場合、関数全体がホイストされます。これは、コードで定義される前に関数を使用できることを意味します。このプロセスでは、実行が開始される前に宣言がスタックに配置されます。
var で宣言された変数は、ホイスティング中に未定義として初期化されます。
関数宣言は完全にホイストされており、コードに書き込む前に呼び出すことができます。
ホイスト プロセスにより、コード内の位置に関係なく、これらの宣言が実行スタック内で確実に認識されます。
宣言のみがホイストされ、割り当てはホイストされないことに注意することが重要です。割り当ては、作成した場所と同じ場所に残ります。
注: ホイスティング中にコードが上部に移動すると言っている人は実際には間違っています。コードは上に移動することはありません。
console.log(myVariable); // undefined var myVariable = 10;
このコードは 2 つのアクションを同時に実行します。まず、変数 myVariable を宣言し、それをスコープにホイストしますが、その値はまだ未定義です。そのため、console.log コマンドでは、初期化されていない値が未定義として表示されます。その後、値 10 が myVariable.
に割り当てられます。ただし、変更しても以前の宣言には影響しません。例えば:
console.log(myVariable); // ReferenceError: myVariable is not defined myVariable = 10;
ここでは、myVariable 変数を宣言していないため、変数を変更しようとする前に ReferenceError がスローされます。
要約すると、JavaScript は最初にすべてのコードを読み取り、次に割り当てを元の位置に保持したまま、すべての宣言を out に巻き上げます。このプロセスはホイスティングとして知られています。
var と let は両方とも JavaScript でホイストされますが、動作は若干異なります。
var を使用して変数を宣言すると、その宣言はスコープ外にホイストされ、宣言前から変数にアクセスできますが、値が割り当てられるまで値は未定義になります。
console.log(myVariable); // undefined var myVariable = 10;
上記のコードでは、宣言 var myVariable がスコープ外にホイストされていますが、割り当て myVariable = 10 はそのまま残されています。したがって、変数は存在しますが値がまだ割り当てられていないため、console.log ステートメントは unknown を出力します。
一方、let を使用して変数を宣言する場合、ホイスティングの動作は少し異なります。変数宣言はホイストされますが、宣言前に変数にアクセスすることはできません。これは「時間的デッドゾーン」として知られています。 let 変数を宣言する前にアクセスしようとすると、ReferenceError.
が発生します。console.log(myVariable); // ReferenceError: myVariable is not defined let myVariable = 10;
この場合、宣言はホイストされますが、宣言の前に変数にアクセスすることはできません。したがって、変数がまだ定義されていないため、console.logstatement は ReferenceError をスローします。
ここで基本的にletの場合、巻き上げても変数の値は未定義のままです。メモリ内にその変数を格納できるスペースがないためです。このため、そのアドレスを参照できません。 myVariable = 10のアドレスがメモリ上にないため参照エラーとなります。
const キーワードを使用すると、定数を作成できます。定数は、値が割り当てられると再割り当てできない変数です。
const PI = 3.142; PI = 22/7; // Attempt to reassign the value of PI console.log(PI); // Output: TypeError: Assignment to constant variable
この例では、PI it を初期値 3.142 の定数として定義します。新しい値を PI に再割り当てしようとすると、定数を再割り当てできないため、TypeError がスローされます。
const PI; console.log(PI); // Output: SyntaxError: Missing initializer in const declaration PI = 3.142;
この場合、定数 PI を初期化せずに宣言します。定数の宣言と初期化を同時に行う必要があるため、このコードは SyntaxError をスローします。
function getCircumference(radius) { console.log(circumference); circumference = PI * radius * 2; const PI = 22/7; } getCircumference(2); // ReferenceError: circumference is not defined
ここでは、getCircumference 関数内で、宣言前にその周囲にアクセスしようとします。変数がまだ定義されていないため、ReferenceError がスローされます。
constを使用する場合は変数を宣言して初期化してから使用する必要があります。
全体として、var と let はどちらも JavaScript でホイストされますが、それらの動作と時間的デッド ゾーンの概念は let 変数にのみ適用されます。 const は、一度初期化すると再割り当てできない定数を作成します。
function hoisted() { a = 20; var b = 100; } hoisted(); console.log(a); // 20 // can be accessed as a global variable outside the hoisted() function. console.log(b); // As it is declared, it is bound within the bounds of the hoisted() function. We cannot print it outside the hoisted() function. output: ReferenceError: b is not defined
関数 hoist() のスコープ内の var message 変数の宣言が関数の先頭に移動していることがわかります。
この問題を回避するために、変数を使用する前に必ず宣言するようにします。
あなたが提供した両方の例では、出力は未定義になります。
function hoist() { console.log(message); var message = 'Hoisting is all the rage!'; } hoist(); // Output: undefined
function hoist() { var message; console.log(message); message = 'Hoisting is all the rage!'; } hoist(); // Output: undefined
どちらの場合も、変数はそれぞれのスコープの先頭にホイストされますが、その後、コードの元の順序で割り当てが行われるため、出力は未定義です。
関数式はホイストされず、式が関数ではなく変数として扱われるため、TypeError がスローされます。
expression(); // Output: "TypeError: expression is not a function var expression = function() { console.log('Will this work?'); };
その名前からわかるように、これは、宣言される前の変数の使用を許容しない、制限された JavaScript の亜種です。厳密モードでコードを実行する:
一部のサイレント JavaScript エラーを明示的なスロー エラーに変更することで排除します。
JavaScript エンジンによる最適化の実行を困難にする間違いを修正します。
変数の宣言を見逃している可能性があります。strict を使用すると、参照エラーが発生して停止します。
'use strict'; console.log(hoist); // Output: ReferenceError: hoist is not defined hoist = 'Hoisted';
変数や関数を宣言するときは、JavaScript でホイスティングを理解することが重要です。ホイスティングについて説明すると、JavaScript コードが実際にどのように処理されるかを理解できるようになります。
免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。
Copyright© 2022 湘ICP备2022001581号-3