検索
ホームページウェブフロントエンドjsチュートリアルJavascriptを理解する_13_実行モデルの詳しい解説_Javascriptスキル

関数実行環境
簡単なコード:
コードをコピー コードは次のとおりです:

function Say(msg,other){
var str = "誰も言いません:";
this.name = '馬鹿の座右の銘'
function method(){};// var method = function(){};
alert(str msg);
say('hello world')
alert(name); // バカのモットー

say メソッドを呼び出すとき、最初のステップはその実行環境を作成することです。実行環境の作成プロセスでは、一連の操作が定義された順序で完了します。
1.アクティブ オブジェクト」が作成されます (アクティブ化オブジェクト)。アクティブ オブジェクトは、仕様で指定されているもう 1 つのメカニズムです。アクセス可能な名前付きプロパティがあるため、オブジェクトと呼ばれますが、通常のオブジェクトのようなプロトタイプ (少なくとも事前定義されたプロトタイプ) はなく、アクティブなオブジェクトは JavaScript コードを通じて直接参照できません。
2. 関数呼び出しの実行環境を作成する次のステップは、引数オブジェクトを作成することです。これは、関数を呼び出すときに渡されるパラメーターを整数インデックスと 1 対 1 対応で格納する配列のようなオブジェクトです。配列のメンバー。このオブジェクトには長さと呼び出し先のプロパティもあります (詳細については、「Javascript_14_Function のパラメータと引数について」を参照してください)。次に、アクティブ オブジェクトに対して「arguments」と呼ばれるプロパティが作成され、前に作成したarguments オブジェクトを参照します。
3. 次に、実行環境にスコープを割り当てます。スコープはオブジェクトのリスト (チェーン) で構成されます。 (さらに複雑です。「JavaScript_15_Scope の割り当てと変数アクセス ルールを理解してクロージャを送信する」を参照してください)
4. その後、ECMA 262 のいわゆる「アクティブ オブジェクト」によって完了した「変数のインスタンス化」が発生します (変数のインストール) プロセス。このとき、関数の仮引数は変数オブジェクトの名前付きプロパティとして作成され、関数呼び出し時に渡される引数が仮引数と一致する場合には、対応する引数の値がこれらの名前付きプロパティに代入されます。プロパティ (そうしないと、名前付きプロパティに未定義の値が割り当てられます)。定義された内部関数の場合、宣言された名前を持つ可変オブジェクト上に同じ名前のプロパティが作成され、対応する内部関数が関数オブジェクトとして作成され、そのプロパティに割り当てられます。変数のインスタンス化の最後のステップは、関数内で宣言されたすべてのローカル変数を可変オブジェクトの名前付きプロパティとして作成することです。注: このプロセスでは、値を持つ実際のパラメーターと関数定義を除き、その他すべては未定義の値として「事前解析」されます。
5 最後に、this キーワードを使用するために値を割り当てる必要があります。 。 (この時点では、グローバル オブジェクト、つまりウィンドウを指します)

実行環境が正常に作成されたら、2 番目のステップに入ります。関数本体の上から下にコードを実行します。
1. var str='nobodysay' が実行されると、「計算代入式」と呼ばれる処理が発生し、アクティブなオブジェクトのキー str の値が unknown から 'nobodysay: に設定されます。 '。
2. this.name='バカの座右の銘' を実行すると、属性名が this としてオブジェクトに追加され、値が 'バカの座右の銘' として割り当てられます。
3. 次に function innerMethod(){ };最後に 'alert(str msg) を実行し、'nobodysay:hello world' を出力します。


function method(){} と var method(){}
簡単なコード:

コードをコピー コードは次のとおりです:
function Say(){
method01();//method01
method02();//エラー
function method01(){
alert('method01')
}
var method02 = function( ) {
alert('method02')
}
}
say();
メソッドmethod01の呼び出しは正常に実行されるのに、メソッドmethod02の呼び出しではエラーが報告されるのはなぜですか?
まず、method01 は関数オブジェクトであり、method02 は別の関数オブジェクトを指す変数であることを明確に理解しておく必要があります。前のセクションの内容によると、「アクティブ オブジェクト」によって完了する「変数の初期化」のプロセスでは、関数メソッド 01 は通常「事前解析」され、変数メソッド 02 は When に入るときに未定義の値に解析されます。コードを実行することになりますが、関数式を計算する前にmethod02が呼び出されるため、メソッド呼び出しとしてunknownが使用されている場合、必然的にエラーが報告されます。解決策は比較的簡単で、method02() の呼び出しの前に var method02=function(){...} を置くか、関数宣言 (function method(){...}) の形式で関数を定義するだけです。
注: 関数式の計算とは、var method02 = function(){...} までプログラムが実行されることを意味します。この時点では実際には、method02 は関数オブジェクトを指しています。 「事前解析」中に、method02 は未定義の

グローバル実行環境 (「実行モデル分析」で既に説明されているため、詳細は説明しません)
にのみ割り当てられたためです。グローバル実行環境は、JS コードが初めてロードされるときに作成されます。グローバル実行環境のスコープ チェーンは、実際には、JavaScript コードの実行を開始する前に、グローバル オブジェクト (ウィンドウ) という 1 つのオブジェクトのみで構成されます。エンジンはこのスコープ チェーン構造を作成します。グローバル実行環境には変数のインスタンス化プロセスもあり、その内部関数は、ほとんどの JavaScript コードを含む通常のトップレベル関数宣言です。さらに、グローバル オブジェクトは変数のインスタンス化中に可変オブジェクトであるため、グローバルに宣言された関数はグローバル オブジェクト プロパティになります。グローバルに宣言された変数にも同じことが当てはまります。グローバル実行環境は、このオブジェクトを使用してグローバル オブジェクトを参照します。

注: 「関数実行環境」のアクティベーション オブジェクトとグローバル実行環境の変数オブジェクトを区別してください (いくつかの違いがあるため、新しい名前が付けられています)。違いを示すために仕様ではグローバル実行環境/Eval 実行環境では Variable オブジェクトと呼ばれ、関数実行環境では Activation オブジェクトと呼ばれます。

Eval 実行環境
Eval 実行環境構築時の変数オブジェクト (Variable Object) は、eval 呼び出し時の現在の実行コンテキストの変数オブジェクト (Variable Object) です。 eval 関数がグローバル実行環境で呼び出される場合、その変数オブジェクト (Variable Object) はグローバル オブジェクトであり、eval 関数が呼び出される場合、その変数オブジェクト (Variable Object) は関数のアクティベーション オブジェクト (Activation Object) になります。
コードをコピー コードは次のとおりです:

//FF2.0、IE7 で渡されます。 、Opera9. 25、Safari3.0.4
function fn(arg){
var innerVar = "関数内の変数";
eval('
var evalVar = "eval 内の変数";
document.write (arg "
");
document.write(innerVar "
");
document.write(evalVar) ;
}
fn("arguments for function");


出力結果は次のようになります:
関数の変数
eval の変数
注: 関数 fn のパラメーターとローカル変数は、eval 呼び出しでアクセスできます。eval で定義されたローカル変数は、変数オブジェクトが同じオブジェクトであるため、関数 fn からもアクセスできます。 。
評価コードの実行に入ると、新しいスコープ チェーンが作成されます。その内容は、現在の実行コンテキストのスコープ チェーンとまったく同じです。


最後の例
コードは次のとおりです:

var innerVar1="グローバル コードの変数";
function fn1(arg1, arg2){
var innerVar1="関数コードの変数"; >関数 fn2() { return innerVar1 " - " innerVar1 " - " " - " (arg1 arg2) }
return fn2();
var innerVar2=fn1(10, 20); 🎜>

実行プロセスは大まかに次のとおりです。
1. ウィンドウ オブジェクトであるグローバル オブジェクトとウィンドウ オブジェクト自体である変数オブジェクトを初期化します。ウィンドウ オブジェクトのみを含むスコープ チェーン オブジェクトをscope_1 であると仮定して、スコープ チェーン オブジェクトを作成します。
2. JS ソース コードをスキャンします (ソース コードを読みます。字句解析および構文解析のプロセスがある場合があります)。その結果から、定義された変数名と関数オブジェクトを取得できます。スキャン順序に従って:
2.1 変数 externalVar1 を検出し、outerVar1 属性をウィンドウ オブジェクトに追加します。値は未定義です。
2.2 関数 fn1 の定義を検出し、この定義を使用して関数オブジェクトを作成します。作成プロセスに渡されるスコープ チェーンはscope_1です。結果を window プロパティに追加します。名前は fn1 で、値は返された関数オブジェクトです。 fn1 の内部 [[Scope]] はscope_1 であることに注意してください。なお、作成処理では関数本体内のJSコードに対して特別な処理は行わず、関数本体内のJSコードのスキャン結果を関数オブジェクトの内部プロパティに保存するだけであることが分かります。関数の実行時に処理されます。これは、関数コード、特に入れ子関数定義における変数のインスタンス化を理解するための鍵です。
2.3 変数 externalVar2 を検出し、outerVar2 属性をウィンドウ オブジェクトに追加します。値は未定義です。
3.そして値を「グローバルコード内の変数」に割り当てます。
4. 関数 fn1 を実行し、戻り値を取得します。
4.1 アクティベーション オブジェクトを作成します (有効化_1 であると仮定します)。新しいスコープ チェーンを作成します (有効範囲_2 の最初のオブジェクトが有効化_1 であると仮定します)。 object はウィンドウ オブジェクトです (fn1 の [[Scope]]、つまり、scope_1 の内容から取得されます)。
4.2 プロセス パラメーター リスト。 activity_1 の属性 arg1 と arg2 にそれぞれ値 10 と 20 を設定します。引数オブジェクトを作成して設定し、引数を activity_1 の属性として設定します。
4.3 fn1 の関数本体に対して手順 2 と同様のプロセスを実行します。
4.3.1 変数 innerVar1 を検出し、innerVar1 属性を追加します。 activity_1 オブジェクト、値は undefine;
4.3.2 関数 fn2 の定義を検出し、この定義を使用して関数オブジェクトを作成し、作成プロセスに渡されるスコープ チェーンはscope_2 です (関数 fn1 のスコープ チェーンは現在の実行コンテキストの内容)。結果を、fn2 という名前と返された関数オブジェクトの値を使用して、activation_1 の属性に追加します。 fn2 の内部 [[スコープ]] はscope_2 であることに注意してください。
4.4 innerVar1 代入ステートメントを実行し、値を「関数コード内の変数」に代入します。
4.5 fn2 を実行します。
4.5.1 アクティベーション オブジェクトを作成します (activation_2 であると仮定します); 新しいスコープ チェーンを作成します (scope_3 であると仮定します)。 . オブジェクト (fn2 の [[Scope]]、つまりscope_2 から取得);
4.5.2 プロセスパラメータリスト。 fn2 にはパラメーターがないため、引数オブジェクトを作成し、それを activity_2 の属性として設定するだけです。
4.5.3 fn2の関数本体に対して手順2と同様の処理を行うと、変数定義や関数宣言が見つかりません。
4.5.4 関数本体を実行します。変数参照の場合、scope_3 から検索します。この例では、outerVar1 は window で見つかり、innerVar1、arg1、および arg2 は activity_1 で見つかります。
4.5.5 スコープ_3 とアクティベーション_2 を破棄します (ガベージ コレクションできることを意味します)。
4.5.6 fn2の戻り値を返します。
4.6 activity_1 とscope_2 を破棄します。
4.7 結果を返します。
5. 結果をouterVar2に代入します。

参考:
http://www.cnblogs.com/RicCC/archive/2008/02/15/JavaScript-Object-Model-Execution-Model.html
http://www .cn-cuckoo.com/2007/08/01/ Understand-javascript-closures-72.html
声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
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は柔軟で、フロントエンドおよびサーバー側のプログラミングで広く使用されています。

Python vs. JavaScript:コミュニティ、ライブラリ、リソースPython vs. JavaScript:コミュニティ、ライブラリ、リソースApr 15, 2025 am 12:16 AM

PythonとJavaScriptには、コミュニティ、ライブラリ、リソースの観点から、独自の利点と短所があります。 1)Pythonコミュニティはフレンドリーで初心者に適していますが、フロントエンドの開発リソースはJavaScriptほど豊富ではありません。 2)Pythonはデータサイエンスおよび機械学習ライブラリで強力ですが、JavaScriptはフロントエンド開発ライブラリとフレームワークで優れています。 3)どちらも豊富な学習リソースを持っていますが、Pythonは公式文書から始めるのに適していますが、JavaScriptはMDNWebDocsにより優れています。選択は、プロジェクトのニーズと個人的な関心に基づいている必要があります。

C/CからJavaScriptへ:すべてがどのように機能するかC/CからJavaScriptへ:すべてがどのように機能するかApr 14, 2025 am 12:05 AM

C/CからJavaScriptへのシフトには、動的なタイピング、ゴミ収集、非同期プログラミングへの適応が必要です。 1)C/Cは、手動メモリ管理を必要とする静的に型付けられた言語であり、JavaScriptは動的に型付けされ、ごみ収集が自動的に処理されます。 2)C/Cはマシンコードにコンパイルする必要がありますが、JavaScriptは解釈言語です。 3)JavaScriptは、閉鎖、プロトタイプチェーン、約束などの概念を導入します。これにより、柔軟性と非同期プログラミング機能が向上します。

JavaScriptエンジン:実装の比較JavaScriptエンジン:実装の比較Apr 13, 2025 am 12:05 AM

さまざまなJavaScriptエンジンは、各エンジンの実装原則と最適化戦略が異なるため、JavaScriptコードを解析および実行するときに異なる効果をもたらします。 1。語彙分析:ソースコードを語彙ユニットに変換します。 2。文法分析:抽象的な構文ツリーを生成します。 3。最適化とコンパイル:JITコンパイラを介してマシンコードを生成します。 4。実行:マシンコードを実行します。 V8エンジンはインスタントコンピレーションと非表示クラスを通じて最適化され、Spidermonkeyはタイプ推論システムを使用して、同じコードで異なるパフォーマンスパフォーマンスをもたらします。

ブラウザを超えて:現実世界のJavaScriptブラウザを超えて:現実世界のJavaScriptApr 12, 2025 am 12:06 AM

現実世界におけるJavaScriptのアプリケーションには、サーバー側のプログラミング、モバイルアプリケーション開発、モノのインターネット制御が含まれます。 2。モバイルアプリケーションの開発は、ReactNativeを通じて実行され、クロスプラットフォームの展開をサポートします。 3.ハードウェアの相互作用に適したJohnny-Fiveライブラリを介したIoTデバイス制御に使用されます。

next.jsを使用してマルチテナントSaaSアプリケーションを構築する(バックエンド統合)next.jsを使用してマルチテナントSaaSアプリケーションを構築する(バックエンド統合)Apr 11, 2025 am 08:23 AM

私はあなたの日常的な技術ツールを使用して機能的なマルチテナントSaaSアプリケーション(EDTECHアプリ)を作成しましたが、あなたは同じことをすることができます。 まず、マルチテナントSaaSアプリケーションとは何ですか? マルチテナントSaaSアプリケーションを使用すると、Singの複数の顧客にサービスを提供できます

next.jsを使用してマルチテナントSaaSアプリケーションを構築する方法(フロントエンド統合)next.jsを使用してマルチテナントSaaSアプリケーションを構築する方法(フロントエンド統合)Apr 11, 2025 am 08:22 AM

この記事では、許可によって保護されたバックエンドとのフロントエンド統合を示し、next.jsを使用して機能的なedtech SaaSアプリケーションを構築します。 FrontEndはユーザーのアクセス許可を取得してUIの可視性を制御し、APIリクエストがロールベースに付着することを保証します

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衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

Safe Exam Browser

Safe Exam Browser

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

WebStorm Mac版

WebStorm Mac版

便利なJavaScript開発ツール

mPDF

mPDF

mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。