window全局做用域->頁面關掉才銷燬
函數執行會造成私有的做用域瀏覽器
1)做用域的銷燬
通常狀況下,函數執行造成一個私有的做用域,當執行完成後就銷燬了->節省內存空間函數
2)做用域的不當即銷燬
function fn(){
var i=10;
return function(n){
console.log(n+i++);
}
}
fn()(15);//->先執行fn,有一個私有的變量i=10,返回一個堆內存地址 xxxfff111,咱們發現這個地址還用到了一次,那麼當前的這個fn造成私有做用域(A)就不能當即銷燬了,xxxfff111(15)->輸出25,A中的i變爲11;當xxxfff111執行完了,發現這個地址沒用了,瀏覽器就把A、xxxfff111都釋放了性能
fn()(20);//->在執行fn的時候一切都重新開始了,和上面的步驟是同樣的->輸出30優化
3)做用域的不銷燬:造成一個私有做用域,裏面的內容被外面佔用了
function fn(){
var i=10;
return function(n){
console.log(n+i++);
}
}
var f=fn();//->fn執行造成一個私有的做用域A,A中有一個私有的變量i=10,A中返回一個地址xxxfff11,被外面的f佔用了,那麼當前的A就不能銷燬了
f(15);//->輸出25,讓A中的i=11
f(20);//->輸出31,讓A中的i=12
...
當咱們知道f用完的時候,爲了優化性能,咱們讓f=null,這樣的話A中的xxxfff111沒人佔用了,瀏覽器會把A和xxxfff111都釋放了動畫
幾種不銷燬經常使用到的形式:
1)函數執行,返回一個引用數據類型的值,而且在函數的外面被別人接收了,那麼當前函數造成的私有做用域就不在銷燬了-->例如上面的案例指針
2)在函數執行的時候,裏面的一個小函數的地址賦值給了咱們的外面元素的點擊事件,那麼當前小函數也至關於被外面佔用了,大函數執行造成的私有的做用域也不銷燬了
//每一次循環都執行自執行函數造成一個私有的做用域(循環三次就有三個做用域,每個做用域中都有一個i,第一個存儲的是0,第二個存數的是1..),在每個私有的做用域中都把裏面的函數綁定給了外面元素的點擊事件,這樣的話每一次造成的做用域都不銷燬了(三個不銷燬的做用域)
var oLis=document.getElementsByTagName("li");
for(var i=0;i<oLis.length;i++){
~function(i){
oLis[i].onclick=function(){
tabChange(i);
}
}(i);
}code
3)在使用setTimeout實現輪詢動畫的時候,咱們若是move須要傳遞參數值,那麼像下面這樣的寫法會行成不少的不銷燬的做用域,很是的耗性能
function move(tar){
<js code>對象
//window.setTimeout(move,10); ->第二次執行move的時候咱們沒有給它傳值(這樣寫不行)
window.setTimeout(function(){
move(tar);
},10);//->這樣寫實現了,可是每一次執行定時器都會造成一個私有的所用域(匿名函數造成的)A,在A中使用了上級做用域中的tar的值,並且執行了move又造成了一個小的做用域(而在小的做用域中會使用tar的值),這樣每一次定時器造成的A都不能銷燬了
}
move(100);//->第一次這樣執行傳遞100事件
//解決辦法:
function move(tar){
~function _move(){
<js code>
window.setTimeout(_move,10);
}();
}
move(100);//->第一次這樣執行傳遞100內存
JS中內存空間釋放的問題(堆內存、棧內存)
[谷歌瀏覽器]
咱們開闢一個內存,可能或有一些其餘的變量等佔用了這個內存,谷歌瀏覽器都會間隔一段時間看這個內存還有沒有被佔用,若是發現有沒有被佔用的內存了,就本身幫咱們回收了(內存釋放)
[火狐和IE]
咱們開個內存,當咱們引用了它,就在內存中記錄一個數,增長一個引用瀏覽器就把這個數+1,減小一個引用,瀏覽器就把這個數-1...當減到零的時候瀏覽器就把這個內存釋放了;可是有些狀況下(尤爲是IE)記着記着就弄亂了,內存就不能釋放了-->瀏覽器的內存泄露
var obj={};咱們養成一個好的習慣,當咱們obj這個對象使用完成了,咱們手動的obj=null (null空對象指針),瀏覽器會本身把剛纔的堆內存釋放掉