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空对象指针),浏览器会本身把刚才的堆内存释放掉