Executeコンテキストベース
11814 ワード
Execute context
まず、JavaScriptは変数を呼び出すとScopeという名前の場所にあります.
💡 Scopeとは?
変数の有効範囲を表す用語
function fn1() {
n1 = "n1"; //1번 코드
var v1 = "v1"; //2번 코드
let l1 = "l1"; //3번 코드
const c1 = "c1"; //4번 코드
fn2();
}
fn1();
上のコードをデバッグして行ごとに実行しましょう.fn 1関数に入ると、Execute contextは次の図のようにCallStackという場所に積み上げられます.
一つの比喩で説明すれば、Call Stackをフォルダと呼び、Scopeをファイルと呼ぶことができます.fn 1フォルダからアクセスできるファイルがfn 1のScopeです.したがって、最初に生成されたExecute context anonymousは、グローバルアクセス可能なExecute contextであるため、グローバルExecute contextとも呼ばれる.すなわち、プライマリコードでは、global executeコンテキストで宣言され、関数の外で宣言されます.
これはExecute ContextがCall Stackの一部であることを示している.
(1枚目写真:fn 1以外のコードでアクセス可能なScopeリスト)
(2枚目の写真:fn 1関数でアクセス可能なScopeリスト)
また、global execute contextの範囲内で変数を宣言する場合.
varまたは何も貼り付けない場合は、Global scopeに変数として格納されます.
letは、constと宣言された場合、Script scopeに格納されます.
アラーム(1)とウィンドウ.コンソールウィンドウでalert(1)を実行したらどうなりますか?
結果は同じです.ウィンドウオブジェクトはグローバルオブジェクトと同じです.したがってalertはグローバル役割ドメイン(windowオブジェクト)で指定されるので、windowオブジェクトと呼ばれても同じ値です.
逆にletとconstとして宣言された変数はScript scopeに格納されます.したがって、ウィンドウ(global scope)オブジェクトから呼び出すことはできません.
上図のfn 1 execute context内に入ってScopeを見ると、Localという名前のScopeが追加されていることがわかります.次に、fn 1関数で1番コードを実行するとglobal scopeでn 1が宣言されます.
今回は2番コードを実行してみましょう.Local Scopeがv 1を生成していることがわかります.
その後、コンソールでv 1、v 0を実行すると、結果値が得られます.v 1はfn 1 ExecuteコンテキストのLocal Scopeで見つかり、v 0はLocal Scopeで見つかり、Script Scopeで見つかりました.
これらのScopeが一緒に接続されていることをScope Chainと呼ぶ.
最後に、3番と4番のコードは実行時にLocal Scopeに指定されます.
💡 GlobalとScript Scopeの違いは何ですか?
Windowsオブジェクトの環境変数(古いスタイル)+語彙として宣言された環境変数(新しいスタイル)の2つの変数を組み合わせてグローバル環境変数と見なします.後者の場合、scriptのscopeとマークします.letとconstは後者なので、グローバル環境ですがwindowオブジェクトにはありません.
ソース:Stackoverflow
letとconstは新しく導入された文法を比較する.ブラウザjsではglobalがwindowが担当し,この分野は多くの変数に囲まれている.さらにユーザ定義のグローバル変数や定数を加えると、様々な問題が発生し、それを防止するために、ユーザ定義データを含むグローバルな範囲が発生することはありません.
出典:生活コード
💡 グローバル宣言の問題
global scopeはすでに様々な値を宣言している.ライブラリなどを含めると、より多くの値が存在し、宣言まですると名前の変更や削除が悪いことが起こります.そのため、大型番組を制作する際、global scopeに声明を発表するのは適切ではない.
fn 2関数に入りましょう.
n0 = "n0";
var v0 = "v0";
let l0 = "l0";
const c0 = "c0";
console.log(v0, n0, l0, c0);
console.log(window.v0, window.n0, window.l0, window.c0);
function fn2() {
n2 = "n2";
console.log(n0, n1, n2);
var v2 = "v2";
console.log(v0, v2);
// console.log(v1)
let l2 = "l2";
console.log(l0, l2);
// console.log(l1);
const c2 = "c2;";
console.log(c0, c2);
// console.log(c1);
}
function fn1() {
n1 = "n1";
var v1 = "v1";
let l1 = "l1";
const c1 = "c1";
fn2();
}
fn1();
(画像:fn 2関数に入った後の変化)
以上のように変化していることがわかります.
fn 1()で実行されているfn 2()を表示します.親と呼べるfn 1()のLocal Scopeはfn 2()のLocalにはなく、fn 2()のLocalのみです.(LexicalScopeの理由を説明)
この状態(fn 2 execute context範囲)で宣言した変数を実行します.上のコードのfn 2 console.ロゴ部分です
n 0、n 1、n 2、v 0は、グローバルな範囲内で正常に動作します.
v 2の場合、fn 2のローカル範囲にあるため、正常に動作します.
v 1の場合、fn 1のローカル範囲内でアクセスできないためエラーが発生します.
l 0の場合、Script scopeにあるため、正常に動作します.
l 2の場合、fn 2のローカル範囲内であるため、正常に動作します.
l 1の場合、fn 1のローカル範囲内でアクセスできないためエラーが発生します.
cの場合はlと同じです.
fn 2()のすべてのコードを実行してから出かけましょう.
Call Stackでは、fn 2 Executeコンテキストが消えます.fn 1を離れる場合も,fn 1はCall Stackから削除され,グローバルexecuteコンテキストのみが残る.
Lexical scope
JavaScriptはLexicalscopeに従います.
Lexicalscopeは、関数をどこで呼び出すかではなく、どこに宣言するかによって決定されます.
JavaScriptはLexical Scopeに従うため、関数の宣言時に親Scopeを決定します.関数をどこから呼び出すかは、スキャン決定に何の意味もありません.
つまり、関数の呼び出しは親スキャンではなく 宣言によって大尉を決める.
Lexicalscopeによる次のコードの結果の予測
var x = 1;
function foo() {
var x = 10;
bar();
}
function bar() {
console.log(x);
}
foo(); // ?
bar(); // ?
上記の例の関数barはグローバルとして宣言されます.したがって、関数バーの親スキャンはグローバルスキャンであり、上記の例ではグローバル変数xの値1を2回出力します.整理する
letとconstは関数だけでなく、blockでもLocal Scopeに入ります.
これに対して、追加学習を行います.
以上で得られた効果
予期せぬ問題が発生した場合、デバッガで現在のステータスを把握し、問題を解決するためのポリシーを育成できます.
参考資料
生活コード
Execution Context | PoiemaWeb
Reference
この問題について(Executeコンテキストベース), 我々は、より多くの情報をここで見つけました https://velog.io/@isthis/Execute-context실행-컨텍스트-기초テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol