JS整理編:関数クローズドの私の理解
3130 ワード
1、クローズドとは何ですか?他の関数の内部変数の関数を読み取ることができます.Javascript言語では、関数内部のサブ関数だけが局所変数を読み取ることができます.(内層作用領域は外層作用領域にアクセスできます.逆はダメです.)ので、クローズドを簡単に「関数の内部に定義された関数」と理解できます.したがって、本質的には、閉じたパケットは関数内部と関数外部をつなぐ橋です.
1.1 なぜクローズドを使うのですか? : グローバル変数と局所変数は、互換性のない優れた欠点を持っています.グローバル変数: 優: 再利用可能です 欠落: 汚染されやすい ローカル変数: 優: 関数内でのみ使用できます.汚染されません. 再利用不可! 1.2 いつクローズドされますか?変数を再利用して、変数が汚染されないように保護する場合、どうやって使いますか? 1.保護する変数と内部関数を外層関数で包む. .外層関数は、内層関数を外部に返す. .外層関数を呼び出し、内層関数を求めるオブジェクトは、外部の変数に保存されます.すなわち、クローズドされています. 1.3 閉包が形成された理由: 外層関数の呼び出し後、外層関数の関数領域(AO)オブジェクトは解放されません. AO参考:第19編js高級知識---品詞分析とAOチェーン 2、閉包による問題:
クローズドはいいですが、メモリ漏れなど一連の問題が発生しました.jsのゴミ回収メカニズムは参照数ですので、変数がもう使われなくなった時(参照は0と数えます.)ゴミ回収メカニズムはクリアされます.クローズドの存在は少なくとも1となります.(1.3を参照してください.) ).
何がクローズドですか?
3、クローズド中のthis
閉じたカバンの中でthisを使うと問題があります.大域関数の中でthisはwindowを指します.関数がメソッドに呼び出されると、thisはこのオブジェクトを指します.しかし、匿名関数の実行環境は大域的で、thisは普通windowを指します.ルビーの本の中の一つの経典的な問題を参照してください.
引用:
C言語のような底の言語には、一般的にメモリ管理インターフェースがあります.例えば
//
function f1() {
var num = 10
num++
return num
}
console.log(f1()) // 11
console.log(f1()) // 11
console.log(f1()) // 11
//
function f2() {
var num = 10
return function () {
num++
return num
}
}
var ff = f2() // :f2
console.log(ff()) //11
console.log(ff()) //12
console.log(ff()) //13
局所変数は関数で、関数の使用が終わると、局所変数は自動的に解放されます.カプセル化後、内部の局所変数の使用はスコープチェーンを延長します. 1.1 なぜクローズドを使うのですか? : グローバル変数と局所変数は、互換性のない優れた欠点を持っています.
クローズドはいいですが、メモリ漏れなど一連の問題が発生しました.jsのゴミ回収メカニズムは参照数ですので、変数がもう使われなくなった時(参照は0と数えます.)ゴミ回収メカニズムはクリアされます.クローズドの存在は少なくとも1となります.(1.3を参照してください.) ).
function f()
{
var myDiv = document.getElementById("Div1")
myDiv.onclick = function()
{
console.log(myDiv.id)
}
}
上記のコードの中で、関数fはmyDivをクリアする必要がありますが、myDivは匿名関数の存在により、少なくとも1の引用数です.したがって、使用されているメモリは永遠に回収されません.関数内の変数はメモリに保存されていますので、メモリの消耗が大きいので、パケットを乱用してはいけません.そうでないと、ウェブページの性能に問題が発生します.IEによる可能性があります.メモリが漏れる. 解決方法は、関数を終了する前に使用しないローカル変数をすべて削除します.function f()
{
var myDiv = document.getElementById("Div1")
var id = myDiv.id
myDiv.οnclick=function()
{
console.log(id)
}
myDiv = null
}
myDiv.idを変数の中に保存し、この変数をクローズドに引用することはmyDivとは関係ないが、クローズドは関数を含む活動対象全体を参照するので、myDivをnullとして参照を解除し、ゴミ回収メカニズムが資源回収できるようにしなければならない.何がクローズドですか?
3、クローズド中のthis
閉じたカバンの中でthisを使うと問題があります.大域関数の中でthisはwindowを指します.関数がメソッドに呼び出されると、thisはこのオブジェクトを指します.しかし、匿名関数の実行環境は大域的で、thisは普通windowを指します.ルビーの本の中の一つの経典的な問題を参照してください.
var name = "The Window"
var object = {
name: "My Object",
getNameFunc: function () {
return function () {
return this.name
}
}
}
console.log(object.getNameFunc()()) // "The Window"
内部関数は、thisを検索すると、そのアクティブなオブジェクトだけが検索されます.匿名関数の実行環境は大域的なので、現在のアクティブなオブジェクトはwindowです. 現在のオブジェクトを変更することで、thisの方向を変更できます.var name = "The Window"
var object = {
name: "My Object",
getNameFunc: function () {
var that = this
return function () {
return that.name
}
}
}
console.log(object.getNameFunc()()) // "My Object"
ここではthisオブジェクトをthat変数に割り当てていますので、現在の活動対象はwindowからobjectになります.引用:
C言語のような底の言語には、一般的にメモリ管理インターフェースがあります.例えば
malloc()
とfree()
があります.一方、JavaScriptは変数(対象、文字列など)を作成する時にメモリを割り当て、それらを使わない時には自動的にリリースします.後のプロセスはゴミ回収といいます.この「自動」は混乱の元です.JavaScriptは混乱の元です.(他の高級言語と)開発者はメモリ管理に関心を持たなくてもいいと思います.これは間違いです.