JavaScript でのホイスティング
ホイスティングとは、変数と関数の宣言が、含まれるスコープ (グローバル スコープまたは関数スコープ) の先頭に移動 (または "ホイスト") される動作です。コードが実行されます。これは、コード内で実際に宣言される前に、変数や関数を使用できることを意味します。
変数での巻き上げ
変数
- var で宣言された変数は、スコープの先頭にホイストされますが、その値は、コード内で代入が行われるポイントまで初期化されません。
console.log(x); // undefined
var x = 5;
console.log(x); // 5
ログイン後にコピー
let と const
- let および const で宣言された変数もホイストされますが、宣言に達するまでは「一時的なデッド ゾーン」に置かれます。宣言される前にアクセスすると、ReferenceError が発生します。
console.log(y); // ReferenceError: Cannot access 'y' before initialization
let y = 10;
// block scope
{
let x = 5;
}
console.log(x); // ReferenceError: x is not defined
ログイン後にコピー
関数でのホイスティング
伝統的な機能
- 関数宣言は完全にホイストされます。つまり、宣言と関数本体の両方がスコープの先頭に移動されます。これにより、コード内で関数を宣言する前に関数を呼び出すことができます。
sayHello(); // "Hello!"
function sayHello() {
console.log("Hello!");
}
ログイン後にコピー
- 対照的に、関数式 (関数が変数に代入されている) は変数としてホイストされるだけなので、変数が初期化される前に関数式を呼び出すと、未定義または TypeError が発生します。
greet(); // TypeError: greet is not a function
var greet = function () {
console.log("Hi!");
};
greet(); // ReferenceError: Cannot access 'one' before initialization
let greet = function () {
console.log("Hi!");
};
ログイン後にコピー
アロー関数
- 対照的に、関数式 (関数が変数に代入されている) は変数としてホイストされるだけなので、変数が初期化される前に関数式を呼び出すと、未定義または TypeError が発生します。
greet(); // TypeError: greet is not a function
var greet = () => {
console.log("Hi!");
};
greet(); // ReferenceError: Cannot access 'one' before initialization
let greet = function () {
console.log("Hi!");
};
ログイン後にコピー
時間的デッドゾーン (TDZ)
let と const を使用して宣言された変数には、時間的デッド ゾーン (TDZ) が存在します。これは、JavaScript が、変数が宣言されて初期化される前にこれらの変数にアクセスできないように設計されているためです。
ホイスティング時に var と let、const が異なる動作をする理由
- それは JavaScript の歴史的な進化によるものです。
- 当初、JavaScript は開発者ではないユーザー向けに設計されており、JavaScript の主な中心的な使用法は、Web ページに小さなインタラクティブな要素を追加することでした。
- したがって、var は機能スコープのみをサポートします。また、当時はブロックスコープはありませんでした。
- しかし、その後の JavaScript の進化では、var の操作やバグの修正がより複雑になりました。
- JavaScript を他の最新言語と競争できるようにするために、let、const、アロー関数、ES6 メソッドなどの機能が追加されました。
var が let や const のように更新されない理由
- これは下位互換性のためです。
- 当時、JavaScript は多くの企業で広く使用されていたため、既存の機能を更新または変更すると、コードベースが破壊されることになります。
- そのため、最新の機能が個別に追加されました。
面接でよくある質問
- JavaScript におけるホイスティングとは何ですか?
- JavaScript では何が巻き上げられ、何が巻き上げられないのでしょうか?
- ホイスティングに関して、var、let、const の違いは何ですか?
- JavaScript の時間的デッド ゾーン (TDZ) とは何ですか?
- 関数宣言と関数式によるホイスティングについて説明できますか?
- ES6 モジュールのホイスティングとは何ですか?
- 実際のコードではホイスティングに依存することを避けるべきなのはなぜですか?
まとめ
- ホイスティングは JavaScript のデフォルトの動作で、コンパイル段階で変数と関数の宣言がそれぞれのスコープの先頭に移動されます。
- ホイスティングは、var および従来の関数で宣言された変数に対してのみ機能し、let、const、および arrow 関数に対しては機能しません。
- 関数宣言のみがホイストされるため、従来の関数は動作しますが、関数が変数に代入されている場合、関数が定義されるまで呼び出し可能になりません。
- var 関数と従来の関数がホイストされるのに let、const、arrow 関数がホイストされない理由は、初期段階では JavaScript が主に小規模な UI インタラクションに使用されていたためです。
- しかしその後、企業によるアプリケーション構築に JavaScript が広く使用されるようになり、グローバル スコープだけでバグを修正することが難しくなりました。
- そのため、将来のアップデートでは、より安全な懸念が解決されました。
- さらに、既存の機能を更新するとコードベースが壊れる可能性があるため、新しい機能は別途追加されました。
以上がJavaScript でのホイスティングを理解する: 包括的なガイドの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。