python闭包的原理_web前端:js 闭包原理
閉包包含自由(未綁定到特定對象)變量;這些變量不是在這個代碼塊內或者任何全局上下文中定義的,而是在定義代碼塊的環境中定義(局部變量)。"閉包"一詞來源于以下兩者的結合:要執行的代碼塊(由于自由變量被包含在代碼塊中,這些自由變量以及它們引用的對象沒有被釋放)和為自由變量提供綁定的計算環境(作用域)。
閉包的定義:閉包是指有權訪問另一個函數作用域中的變量的函數--《Javascript高級程序設計》。
如何理解這句話:其實就是指在函數a外面能夠訪問函數a里面的函數b。
例如:
functiona(){
varv=123;
functionb(){
console.log(v);
}
returnb;
}
varb=a();
b();//123
執行函數a時把函數b返回,此時函數b就保存到了a的外面,這時候就可以在a函數的外部對b進行訪問。
相關知識點:js作用域鏈
執行原理:
1、首先在預編譯全局代碼時,生成GO
GO{
a:functiona(){...},
b:undefined
}
2、執行varb=a();此時對a函數進行預編譯并創建a函數的AO
AO{
v:undefined,
a:undefined,
b:functionb(){...}
}
3、創建a函數的作用域鏈
a.[[Scopes]]=[AO,GO];
4、由于函數的提升,會在a函數進行預編譯的時候創建b函數的AO
bAO{}
b.[[Scopes]]=[AO(b),AO(a),GO]
5、執行varv=123;在js預編譯中提到由于varv的聲明已經得到了提升,所以此時只執行v=123;對AO里的v進行賦值。
AO{
v:123,
a:undefined,
b:functionb(){...}
}
6、之后將函數b返回,此時a函數執行完畢,a函數對應的AO理應銷毀,但是由于在b函數中又對a函數的AO中的變量進行應用,所以a函數的AO不能被垃圾回收機制銷毀,但是會跟a函數斷開聯系,當a函數再次執行,會重新創建一個a函數的AO。
7、在全局變量中使用b接收函數a的返回,此時GO變為
GO{
a:functiona(){...},
b:functionb(){...}
}
8、全局里的b
在b函數中打印v變量,由于b函數的AO中沒有v變量,所以順著作用域鏈往上找,在a的AO中找到v并打印。
閉包優缺點:
優點:
1、屬性的私有化,在b返回后,處理b函數中能對v進行操作,其它地方都不能對v進行操作。
2、防止變量污染。
缺點:
容易造成內存泄漏,因為如果后期不對全局中的b進行處理(例如:賦值為null),a函數的AO會一直存在于內存中,如果多次調用a函數,容易導致內存中的垃圾數據越來越多造成內存泄漏。
在php、Scala、Scheme、CommonLisp、Smalltalk、Groovy、JavaScript、Ruby、Python、Go、Lua、objectivec、Swift以及java(Java8及以上)等語言中都能找到對閉包不同程度的支持。
總結
以上是生活随笔為你收集整理的python闭包的原理_web前端:js 闭包原理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 以下描述中不属于python语言控制结构
- 下一篇: okhttp连接池_OkHttp配置HT