検索

JavaScriptでの巻き上げの詳細説明

Aug 20, 2017 am 10:10 AM
javascriptjs

関数宣言と変数宣言は、JavaScript インタープリターによって常にそれらを含むスコープの先頭に暗黙的にホイストされます。以下の記事ではJavaScriptのホイスティング(変数ホイスティングと関数宣言ホイスティング)に関する情報を中心に紹介していますので、困っている方はぜひ参考にしてみてください。

この記事では主に JavaScript のホイスティング (変数ホイスティングと関数宣言ホイスティング) に関連する内容を紹介し、参考と学習のために共有します。以下では多くを述べませんが、詳細な紹介を見てみましょう。

関数宣言/変数をスコープの先頭に「移動」する方法。

ホイスティングという用語は、識別子の解析を説明するために多くの JavaScript ブログ投稿で使用されています。実際、ホイスティングという言葉は、変数や関数の宣言が関数またはグローバル スコープの先頭にどのようにホイストされるかを説明するために使用されます。この用語はどの JavaScript ドキュメントにも記載されておらず、私たちがホイスティングと呼んでいるものは、その文字通りの意味を比喩として使用しているだけです。

JavaScript のスコープの仕組みについてすでに基本を理解している場合は、ホイスティングをより深く理解することで、より強力な基盤を構築することができます。 (Fool's Wharf からのメモ: JavaScript の一般的な概念として、変数ホイスティングと関数宣言ホイスティングは、フロントエンド開発の面接でよく質問されたり、フロントエンド開発の筆記試験の問題に出題されます。これは、ホイスティング (ホイスティング) を理解することの重要性を示しています。 .)

基本をよりよく理解するために、「ホイスティング」が実際に何を意味するのかを確認してみましょう。また、JavaScript はインタープリタ型言語であり、コンパイル済み言語とは異なります。つまり、JS コードが 1 行ずつ実行されることを意味します。

次の例を考えてください:


console.log(notyetdeclared);
// 打印 'undefined'
 
var notyetdeclared = 'now it is declared';
 
hoisting();
 
function hoisting(){
 console.log(notyetdeclared);
 // 打印 'undefined'
 
 var notyetdeclared = 'declared differently';
 
 console.log(notyetdeclared);
 // 打印 'declared differently'
}

上記のコード例を分析した後、いくつかの質問をしてください:

  • 6 行目、なぜこの関数が宣言される前にアクセスできるのでしょうか?

  • 1行目ではエラーがスローされていませんが、この時点では変数notyetdeclaredが存在しないためでしょうか?

  • 4 行目で notyetdeclared がグローバル スコープで宣言されていますが、9 行目で出力されたときにまだ未定義なのはなぜですか?

JavaScript は非常に論理的であり、これらの奇妙な問題にはすべて明確な説明があります。

上から始めて、JavaScript でコードが実行されるときに実行コンテキストが確立されることを説明しましょう。 JavaScript には、グローバル実行コンテキストと関数実行コンテキストという 2 つの主なタイプの実行コンテキストがあります (Fool's Pier 注: 実行コンテキストは、私たちが通常話しているコンテキストとは異なるという事実に特に注意してください。実行コンテキストはスコープを指し、通常のコンテキストは this が指す値です)。 JavaScript はシングルスレッド実行モデルに基づいているため、一度に実行できるコードは 1 つだけです。

上記のコードのプロセスは、図に示すとおりです:

上記のサンプルコードのコールスタック:

  • プログラムはスタック上のグローバル実行コンテキストから実行を開始します。 。

  • hoisting() 関数が呼び出されると、新しい関数実行コンテキストがスタックにプッシュされ、グローバル実行コンテキストが一時停止されます。

  • hoisting() の実行が完了すると、hoisting() 実行コンテキストがスタックからポップされ、グローバル実行コンテキストが復元されます。

この手順は一目瞭然ですが、サンプル コードの実行時に発生した例外については実際には説明されていません。実行コンテキストがコードの実行を追跡するのに対し、字句環境は識別子の特定の変数へのマッピングを追跡します。字句環境は基本的に JavaScript のスコープ メカニズムの内部実装です。通常、字句環境は、コードの関数や for ループ ブロックなど、JavaScript コードの特定の構造に関連付けられます。関数が作成されるたびに、その関数が作成された字句環境への参照が [[Environment]] という内部プロパティに渡されます。

これらの用語はすべて、シンプルかつ非常に論理的な概念をカバーしています。壊れるのを許してください。字句環境は、コード ブロック内の変数と関数を追跡するために使用される興味深い名前です。各字句環境は、ローカル変数、関数宣言、パラメータの追跡に加えて、その親字句環境も追跡します。したがって、上記のサンプル コードは JavaScript エンジンで次のように解析されます。上記のコードの語彙環境は図に示すとおりです。

注:

理解に問題がある場合は、次の 3 つの記事を確認してください:

  • JavaScript のスコープとコンテキスト

  • JavaScript のスコープとクロージャの中心概念

  • JavaScript スコープの分析例

字句環境で識別子を解決するために、JavaScript エンジンは現在の環境への参照をチェックします。参照が見つからない場合は、[[環境]] を使用して外部環境に移動します。これは、識別子が見つかるか、「未定義」エラーがスローされるまで続きます。

基本的に、JavaScript コードの実行は 2 つの段階に分かれています。最初のフェーズでは、すべての変数と関数の宣言を現在の字句環境に登録します。完了すると、JavaScript 実行の第 2 フェーズが始まります。

フェーズ 1 について詳しく説明すると、2 つのステップで動作します。

  • 現在の関数宣言内のコードをスキャンします。関数式とアロー関数はスキップされます。検出された関数ごとに、新しい関数が作成され、関数名を使用して環境にバインドされます。識別子の名前がす​​でに存在する場合、その値は上書きされます。

  • 次に、現在の環境の変数をスキャンします。 var で定義された変数や、他の関数の外に配置された変数を検索し、値が unknown に初期化された識別子を登録します。識別子が存在する場合、値は変更されません。

注: let および const で定義されたブロック変数は、var とは少し異なります。これについては別の記事で詳しく説明します。

これで、字句環境の基本概念をある程度理解できたはずなので、サンプルコードに戻ってこれらの問題を説明しましょう。

グローバルコンテキストを設定するとき、環境がスキャンされ、hoisting() 関数が識別子に付加されます。次に、次のステップで、変数 notyetdeclared が登録され、その値が unknown に初期化されます。コードの理解を続けるには、次の手順に従ってください。

それでは、サンプルコードで提起された 3 つの質問について説明しましょう:

6 行目、なぜこの関数が宣言される前にアクセスできるのでしょうか?

フェーズ 1 では、hoisting() 関数が識別子に登録されています。JS コードがフェーズ 2 のグローバル実行コンテキストで実行を開始すると、hoisting の字句環境が検索され、その定義の前に見つかります。関数。

1行目ではエラーが出ていませんが、この時点では変数notyetdeclaredが存在しないためでしょうか?

同様に、notyetdeclared はフェーズ 1 で識別子に登録され、未定義に初期化されるため、エラーはスローされません。

最後に、

4 行目の notyetdeclared がグローバル スコープで宣言されているのに、9 行目に出力されたときにまだ未定義なのはなぜですか?

今度は関数ホイスティング環境に入ります。フェーズ 1 では、notyetdeclared の変数がこの字句環境にまだ登録されていないため、notyetdeclared が登録され、未定義に初期化されます。 12 行目に var キーワードが含まれていない場合は、状況は異なります。

JavaScript におけるホイスティングは、技術的に言えば、関数や変数がどこにも移動しないということを説明するために使用する単なる視点であることが明らかになったことを願います。

概要

以上がJavaScriptでの巻き上げの詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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

CおよびJavaScriptは、WebAssemblyを介して相互運用性を実現します。 1)CコードはWebAssemblyモジュールにコンパイルされ、JavaScript環境に導入され、コンピューティングパワーが強化されます。 2)ゲーム開発では、Cは物理エンジンとグラフィックスレンダリングを処理し、JavaScriptはゲームロジックとユーザーインターフェイスを担当します。

Webサイトからアプリまで:JavaScriptの多様なアプリケーションWebサイトからアプリまで:JavaScriptの多様なアプリケーションApr 22, 2025 am 12:02 AM

JavaScriptは、Webサイト、モバイルアプリケーション、デスクトップアプリケーション、サーバー側のプログラミングで広く使用されています。 1)Webサイト開発では、JavaScriptはHTMLおよびCSSと一緒にDOMを運用して、JQueryやReactなどのフレームワークをサポートします。 2)ReactNativeおよびIonicを通じて、JavaScriptはクロスプラットフォームモバイルアプリケーションを開発するために使用されます。 3)電子フレームワークにより、JavaScriptはデスクトップアプリケーションを構築できます。 4)node.jsを使用すると、JavaScriptがサーバー側で実行され、高い並行リクエストをサポートします。

Python vs. JavaScript:ユースケースとアプリケーションと比較されますPython vs. JavaScript:ユースケースとアプリケーションと比較されますApr 21, 2025 am 12:01 AM

Pythonはデータサイエンスと自動化により適していますが、JavaScriptはフロントエンドとフルスタックの開発により適しています。 1. Pythonは、データ処理とモデリングのためにNumpyやPandasなどのライブラリを使用して、データサイエンスと機械学習でうまく機能します。 2。Pythonは、自動化とスクリプトにおいて簡潔で効率的です。 3. JavaScriptはフロントエンド開発に不可欠であり、動的なWebページと単一ページアプリケーションの構築に使用されます。 4. JavaScriptは、node.jsを通じてバックエンド開発において役割を果たし、フルスタック開発をサポートします。

JavaScript通訳者とコンパイラにおけるC/Cの役割JavaScript通訳者とコンパイラにおけるC/Cの役割Apr 20, 2025 am 12:01 AM

CとCは、主に通訳者とJITコンパイラを実装するために使用されるJavaScriptエンジンで重要な役割を果たします。 1)cは、JavaScriptソースコードを解析し、抽象的な構文ツリーを生成するために使用されます。 2)Cは、Bytecodeの生成と実行を担当します。 3)Cは、JITコンパイラを実装し、実行時にホットスポットコードを最適化およびコンパイルし、JavaScriptの実行効率を大幅に改善します。

JavaScript in Action:実際の例とプロジェクトJavaScript in Action:実際の例とプロジェクトApr 19, 2025 am 12:13 AM

現実世界でのJavaScriptのアプリケーションには、フロントエンドとバックエンドの開発が含まれます。 1)DOM操作とイベント処理を含むTODOリストアプリケーションを構築して、フロントエンドアプリケーションを表示します。 2)node.jsを介してRestfulapiを構築し、バックエンドアプリケーションをデモンストレーションします。

JavaScriptとWeb:コア機能とユースケースJavaScriptとWeb:コア機能とユースケースApr 18, 2025 am 12:19 AM

Web開発におけるJavaScriptの主な用途には、クライアントの相互作用、フォーム検証、非同期通信が含まれます。 1)DOM操作による動的なコンテンツの更新とユーザーインタラクション。 2)ユーザーエクスペリエンスを改善するためにデータを提出する前に、クライアントの検証が実行されます。 3)サーバーとのリフレッシュレス通信は、AJAXテクノロジーを通じて達成されます。

JavaScriptエンジンの理解:実装の詳細JavaScriptエンジンの理解:実装の詳細Apr 17, 2025 am 12:05 AM

JavaScriptエンジンが内部的にどのように機能するかを理解することは、開発者にとってより効率的なコードの作成とパフォーマンスのボトルネックと最適化戦略の理解に役立つためです。 1)エンジンのワークフローには、3つの段階が含まれます。解析、コンパイル、実行。 2)実行プロセス中、エンジンはインラインキャッシュや非表示クラスなどの動的最適化を実行します。 3)ベストプラクティスには、グローバル変数の避け、ループの最適化、constとletsの使用、閉鎖の過度の使用の回避が含まれます。

Python vs. JavaScript:学習曲線と使いやすさPython vs. JavaScript:学習曲線と使いやすさApr 16, 2025 am 12:12 AM

Pythonは、スムーズな学習曲線と簡潔な構文を備えた初心者により適しています。 JavaScriptは、急な学習曲線と柔軟な構文を備えたフロントエンド開発に適しています。 1。Python構文は直感的で、データサイエンスやバックエンド開発に適しています。 2。JavaScriptは柔軟で、フロントエンドおよびサーバー側のプログラミングで広く使用されています。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

VSCode Windows 64 ビットのダウンロード

VSCode Windows 64 ビットのダウンロード

Microsoft によって発売された無料で強力な IDE エディター

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser は、オンライン試験を安全に受験するための安全なブラウザ環境です。このソフトウェアは、あらゆるコンピュータを安全なワークステーションに変えます。あらゆるユーティリティへのアクセスを制御し、学生が無許可のリソースを使用するのを防ぎます。

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

SublimeText3 英語版

SublimeText3 英語版

推奨: Win バージョン、コードプロンプトをサポート!