温故知新-JavaScriptのCloureを再認識する
8313 ワード
閉塞の温度
定義:Cloureとは何ですか?
MDN:Close uresの定義は以下の通りである.
A
closure is the commbination of a function bundled together(enclosed)with references to its surrounding state(the)
lexical environment).In other words,a closure gives you access to an outer function's scope from an inner function.In JavaScript,closures are are created every time a function is created,at function creation time.
また、専門性からの説明を見てください.
In programming laggage、a
closure、also
lexical closure or
function closure,is a technique for implementing lexically scoped name binding in a langgage with first-class functions.Operations,a closure is a recording stored a function together with and environment.The enviroting manctions.The engment.The envirotions mancting manctions.The enping manciancting mancting mancting mancting
free variable of the function(variables that are used locally、but defined in an enclosing scope)with the value or reference to which the name was bound when the closure wast created.Unike a pleance the funce
captured variables through the closure's copies of their values or references,even when the function is invoked outside their scope.
簡単に言えば、
いくつかの点に注意が必要です. a closure is a recordクローズドは、関数(通常はその入口アドレス)と、関数を表す環境(シンボルルックアップテーブルに相当)を格納する構造体である. free variable自由変数(関数の外部で定義されていますが、関数内で参照されている変数).クローズドと関数の最大の違いは、クローズドパケットを捕捉すると、その自由変数がキャプチャー時に決定され、キャプチャ時のコンテキストから逸脱しても、通常どおりに動作することができることである. 下記のコードを見てください. Step 1:プログラムが があります. Step 2:プログラムが があります. Step 3:プログラムが
内部関数が外部関数宣言の変数を使用しない場合、インスタンスのデバッグを変更してみます.
MDNの中で言及します
In JavaScript、closures are created evertime a function is created、at function creation time.
次に
ここで、閉包による必要条件をまとめます. 関数には内部関数、すなわち関数ネスト があります.内部関数には、外部関数のいずれかを参照する変数、すなわち、自由変数 が存在する.内部関数が実行される .
解析:なぜ
まず結論を出すと、クローズドパケットがメモリに常駐する理由は、クローズドされているは、最初に実行し、グローバル を作成する.は に入ります.は1つのオブジェクトに戻り、2つの関数が含まれている です.は を継続する.は、 大体の過程はこうです.FuntionInitializeについては、
Type
Description
Lexical Evironment
The Lexical Evironment that the function was closed over.Used as the outer environment when evaluating the code of the function.
前の
また、
The outer reference of a(inner)Lexical Evironment is a reference to the Lexical Evironment that logcal surrounds the inner Lexical Evironment.
締め括りをつける
参考資料万次元百科Cloure) MDN Cloures ECMAScript® 2019 Language Specification クローズドを解読して、今度はECMAScriptの語法環境から、文脈を実行して言います。 すべての書簡式は全部クローズドです。JSの役割領域とCloseureを話します。
定義:Cloureとは何ですか?
MDN:Close uresの定義は以下の通りである.
A
closure is the commbination of a function bundled together(enclosed)with references to its surrounding state(the)
lexical environment).In other words,a closure gives you access to an outer function's scope from an inner function.In JavaScript,closures are are created every time a function is created,at function creation time.
また、専門性からの説明を見てください.
In programming laggage、a
closure、also
lexical closure or
function closure,is a technique for implementing lexically scoped name binding in a langgage with first-class functions.Operations,a closure is a recording stored a function together with and environment.The enviroting manctions.The engment.The envirotions mancting manctions.The enping manciancting mancting mancting mancting
free variable of the function(variables that are used locally、but defined in an enclosing scope)with the value or reference to which the name was bound when the closure wast created.Unike a pleance the funce
captured variables through the closure's copies of their values or references,even when the function is invoked outside their scope.
簡単に言えば、
closure
は、関数とその関数を宣言するロケーションから構成されている.いくつかの点に注意が必要です.
var a = 1;
function test() {
const b = 1;
function inner1() {
var c = a + 2;
function inner2() {
var d = a + b;
return c;
};
inner2()
};
inner1();
}
test();
Chrome
を使用して、それぞれinner1()
、inner2()
、return c
の3箇所でブレークポイント調整を行う.inner1()
まで動作します.コンソールでScope
を見ることができます.Local
とGlobal
の2つのinner2()
に実行されます.Scope
の中にLocal
、Closure(test)
、Global
の3つがあります.Closure(test)
の中に関数test
で定義されている変数b
return c
に実行され、Scope
にLocal
、Closure(test)
、Closure(inner1)
、Global
、Closure(test)
、test
の4つの項目がコンソールで見られます.b
には関数Closure(inner1)
で定義されている変数inner1
があります.内部関数が外部関数宣言の変数を使用しない場合、インスタンスのデバッグを変更してみます.
var a = 1;
function test() {
const b = 1;
function inner1() {
var c = a + 2;
function inner2() {
var d = a + c;
return c;
};
inner2()
};
inner1();
}
test();
前のステップに従って調整を続けていくと、プログラムがc
まで実行されていることが分かります.inner2()
にはScope
がありません.表示された結果:内部関数は、外部関数の変数を参照しないと、クローズドされません.MDNの中で言及します
In JavaScript、closures are created evertime a function is created、at function creation time.
次に
Closure(test)
概念をレビューすると、関数入口アドレスと関連する環境を含む.これは関数が作成された時と同じです.この角度から見れば、関数は閉じられています.理論的には、上記の例はクローズドが発生するはずですが、実際にclosure
でデバッグが発見されていません.ここで最適化が行われていますか?自由変数がない場合は、クローズド処理は行われません.資料を探しましたが、これは確かにコンパイル技術です.chromeといいます.ここで、閉包による必要条件をまとめます.
解析:なぜ
Lambda lifting
はメモリに常駐しているのですか?まず結論を出すと、クローズドパケットがメモリに常駐する理由は、クローズドされている
closure
が解放されていないことにある.function test() {
var a = 0;
return {
increase: function() { a++; },
getValue: function() { return a; },
};
}
var obj = test();
obj.getValue();
obj.increase();
obj.getValue();
分析して実行するプロセス:lexical environment
GlobalExecutionContext = {
LexicalEnvironment: {
EnvironmentRecord: {
Type: "Object",
test: < func >
}
outer: ,
ThisBinding:
},
VariableEnvironment: {
EnvironmentRecord: {
Type: "Object",
// Identifier bindings go here
obj: undefined,
}
outer: ,
ThisBinding:
}
}
lexical environment
関数を実行し、test
関数のtest
FunctionExecutionContextOfTest = {
LexicalEnvironment: {
EnvironmentRecord: {
Type: "Object",
}
outer: ,
ThisBinding:
},
VariableEnvironment: {
EnvironmentRecord: {
Type: "Object",
a: 0,
}
outer: ,
ThisBinding:
}
}
lexical environment
FunctionExecutionContextOfIncrease、
FunctionExecutionContextOfGetValue: {
LexicalEnvironment: {
EnvironmentRecord: {
Type: "Object",
}
outer: ,
ThisBinding:
},
VariableEnvironment: {
EnvironmentRecord: {
Type: "Object",
}
outer: ,
ThisBinding:
}
}
lexical environment
のobj
関数を呼び出し、getValue
の関数のgetValue
に入り、規則に従ってlexical environmentによってGetIdentifierReference(lex, name, strict)
を解析し、a
の関数のincrease
においてlexical environment
を解析できないと、a
の対応する外部outer
に移ってlexical environment
の中で解析obj
のincrease
関数を呼び出し、プロセスは、obj
のgetValue
関数を呼び出すのと同様である.4.Set F.[[Environment]] to Scope.
が見られます.[[Environment]]
に関する仕様の説明を見てください.Type
Description
Lexical Evironment
The Lexical Evironment that the function was closed over.Used as the outer environment when evaluating the code of the function.
obj
のgetValue
関数を呼び出して、outer
の対応する外部lexical environment
に移って解析を続けます.ここでのlexical environment
は、関数の内部属性[[Scopes]]
を指すべきです.前の
chrome
でデバッグした例では、Scope
にClosure(test)
が現れ、中にはtest
関数enviroment record
において他のlexical environment
によって参照されている部分が残っていることがわかる.また、
obj.getValue()
はGlobal lexical environment
で呼び出され、実行されるとき、outer
はGlobal lexical environment
ではない.これは外部語環境参照が論理的に内部語法環境を囲む用語環境を指すからである.The outer reference of a(inner)Lexical Evironment is a reference to the Lexical Evironment that logcal surrounds the inner Lexical Evironment.
締め括りをつける
closure
、関連資料を探して改めて認識し、規範を読んで、専門的な定義を理解する.もとは多くのものは表面の上でそんなに簡単ではありません!参考資料