闭包是指有权访问另一个函数作用域中的变量的函数,创建闭包的常见的方式,就是在一个函数内部创建另一个函数,通过另一个函数访问这个函数的局部变量。
作用域:
1.全局作用域
(1)最外层函数和在最外层函数外面定义的变量拥有全局作用域
(2)所有末定义直接赋值的变量自动声明为拥有全局作用域
(3)所有window对象的属性拥有全局作用域
一般情况下,window对象的内置属性都拥有全局作用域,例如window.name、window.location、window.top等等
2.局部作用域(函数作用域)
(function(){
alert('hello');
})(); //匿名函数调用的第二种方式 把匿名函数包装成一个表达式 自我执行的闭包
function box(){
var a = 10;
function box1(){
// alert("hello");
alert(a);
}
box1();
}
box();
// alert(a);//无法访问a
// function con(){
// alert(a);
// }
function box(){
a = 10; //所有未声明直接使用的变量自动变为全局变量
return (function(){
return a;
})();
}
// alert(box())
box();
alert(a);
function box(x,y){
// return x + y;
// }
// alert(box(2,7));
// var b = function (x,y){
// return x + y;
// }
// b(20,10);
(function(x,y){
alert(x + y);
})(2,6);
从看不到====>看到 淡入
function fadeIn(){
for(var i = 0;i <= 100;i++){
(function(num){
setTimeout(function(){
pic.style.opacity = num /100;
pic.style.filter = "alpha(opacity=" + num +")";
},num * 50);
})(i);
}
}
//从看得到 =====》看不到 opacity 1====》0 淡出
function fadeOut(){
for(var i = 0;i <= 100;i++){
(function(){
var po = i;
setTimeout(function(){
pic[1].style.opacity = po / 100;
pic[1].style.filter = "alpha(opacity=" + po + ")";
},50 * (100-po));
})();
}
}
//调节透明的的函数
function setOpacity(elem,level){ //level [0 ,100]
if(elem.filters){ //ie 滤镜
elem.style.filter = "alpha(opacity=" + level +")";
}else{
elem.style.opacity = level / 100;
}
}
//淡入函数 从看不到====》看的到
function fadeIn(elem){
setOpacity(elem,0);//先把透明度设置为0
for(var i = 0;i <= 100;i++){
(function(){
var pos = i;
setTimeout(function(){
setOpacity(elem,pos);
},pos * 20);
})();
}
}
//淡出效果 从看到===》看不到
function fadeOut(elem){
for(var i = 0;i <= 100;i++){
(function(){
var pos = i;
setTimeout(function(){
setOpacity(elem,pos);
},(100 - pos) * 20);
})();
}
}
内存泄漏
由于IE的JScript对象和DOM对象使用不同的垃圾收集方式,因此闭包在IE中会导致一些问题。就是内存泄漏的问题,也就是无法销毁驻留在内存中的元素。以下代码有两个知识点还没有学习到,一个是DOM,一个是事件。
function box() {
var oDiv = document.getElementById('oDiv'); //oDiv用完之后一直驻留在内存
oDiv.onclick = function () {
alert(oDiv.innerHTML); //这里用oDiv导致内存泄漏
};
}
box();
那么在最后应该将oDiv解除引用来避免内存泄漏。
function box() {
var oDiv = document.getElementById('oDiv');
var text = oDiv.innerHTML;
oDiv.onclick = function () {
alert(text);
};
oDiv = null; //解除引用
}
PS:如果并没有使用解除引用,那么需要等到浏览器关闭才得以释放。
for(var i=0;i<5;i++){
setTimeout(function(){alert(i)},2000);
}
for(var i=0;i<5;i++){
(function(){
setTimeout(function(){ alert(i);},2000);
})();
}
说明:
1.会弹出5个5
2.第一次弹出会延迟2s,其余会接着弹出,没有延迟
3.因为异步函数必须等主进程运行完毕才会运行,setTimeout()内部
回调运行的时候,主进程已经运行完毕了,此时i=5,所以输出5。