クロージャの形成:関数の参照と周囲の状態(字句環境)がバンドルされてクロージャを形成します。
クロージャは、スコープ内の関数の内部関数を呼び出し、関数のスコープ内のメンバーにアクセスできます。
簡単な理解は、外部関数の内部メンバーの範囲を拡張することです。ここで、少し知識を追加する必要があります。
関数が実行されると、実行スタックに配置され、関数が実行されると、実行スタックから削除されます
が、閉じられます。発生した場合、ヒープ上のスコープメンバーは外部参照されているため解放できないため、関数は引き続き外部関数のメンバーにアクセスできます。
次のボタンを見てください。これはクロージャの単純なアプリケーションです。
// 函数作为返回值
function makeFn(){
let msg = "hello Closure!"
return function(){
console.log(msg)
}
}
原理は、外部関数makeFn内部のメンバーのMSGがある拡張するスコープ
次に、chromeのdevtoolを使用してクロージャの発生を観察し
ます。49行目にブレークポイントを設定し、右側の実行スタックとスコープに注意して、段階的にデバッグを開始します。
実行の開始時に、makeFn関数を実行スタックにプッシュし、これがウィンドウを指すスコープ、msgの変数宣言がプロモートされ、
実行を続行するために未定義の値が割り当てられていることを確認します。msgに
値を割り当て、戻り値は、
2つのステップを実行し続ける関数です。返された関数内に入ると、クロージャはクロージャです。同時に、msgはクロージャ
に格納されて実行を継続し、msgの内容が出力されます。クロージャーが表示されたとき、つまりクロージャーが発生したとき、msgは解放されないことがわかりました。したがって、引き続きアクセス可能です。
クロージャーの例をいくつか挙げてください。
// once
function once(fn){
let done = false
return function(){
if(!done){
done = true
return fn.apply(this ,arguments)
}
}
}
let print = once(function (msg) {
console.log(msg)
})
// print("666")
// print("666")
// print("666")
// print("666")
// 延长了外部函数的内部成员的作用范围
// 计算底数的几次幂
function makePow (exponent){
return function(buttomNuber){
return Math.pow(buttomNuber,exponent)
}
}
// console.log(makePow(2)(2))
// 闭包累加器
function add(){
let sum = 0
return function(){
console.log( ++ sum)
}
}
// var myadd = add()
// myadd()
// myadd()
// myadd()
// myadd()
参考資料:
教育の撤回