什么是闭包?
闭包指的是:能够访问另一个函数作用域的变量的函数。
不同于一般函数,它允许一个函数在立即词法作用域外调用时,仍可以访问非本地变量。
示例:
function outer(){
var localVal = 30;
return function(){
return localVal;
};
};
var func = outer();
func();
闭包常见错误循环
document.body.innerHTML='<div id=div1>aaa</div><div id=div2>aaa</div><div id=div3>aaa</div>'
for(var i =1;i<4;i++){
//点击enter后 循环就结束了
document.getElementById('div'+i).
addEventListener('click',function(){
//当点击的时候,由于循环结束,i为4 所以就直接为4了。可以把闭包理解为回调函数。
alert(i)
//all are 4
})
};
//更改为:
document.body.innerHTML='<div id=div1>aaa</div><div id=div2>aaa</div><div id=div3>aaa</div>'
for(var i =1;i<4;i++){
console.log("i",i);
!function(i)
document.getElementById('div'+i).addEventListener('click',function(){
alert(i)
})
}(i);//直接创建一个立即执行的函数,循环的时候就调用,添加监听事件。
}
闭包使用:封装
(
function(){
var _userId = 234;
var _typeId = 'item';
var exports = {};
function coverter(userId){
return userId
};
exports.getUserId = function(){
return coverter(_userId);
};
exports.getTypeId = function(){
return _typeId
};
window.export = exports;
}()
)
window.export.getUserId();//234
window.export.getTypeId();//"item"
_userId //_userId is not defined
总结
优点:灵活方便/封装
缺点:空间浪费,内存泄漏,性能消耗。
作用域
全局作用域
var a = 20;
console.log(a);//20
函数独立作用域
(
function(){
var b = 20;
}
)();
console.log(b);//b is not defined
eval作用域
eval("var a = 1;");
console.log(a);// 1
没有块级作用域
for(var i=0 ;i<5;i++){
console.log(i)
};//0 1 2 3 4
console.log("out",i);// out 5
闭包可以访问外层的函数作用域
//示例1:
function outer2(){
var local2 =2;
function outer3(){
var local1 =1;
console.log(local1,local2)
}
outer3();
}
outer3();//outer3 is not defined
outer2();//1 2
outer3();//outer3 is not defined
//示例2:
function outer2(){
var local2 =2;
//没用用var 说明是全局变量,
outer1 = function (){
var local1 =1;
console.log(local1,local2)
}
outer1();
}
outer1();//outer1 is not defined
outer2();//1 2
//调用了outer2()后 outer1就被定义。
outer1();//1 2
//示例3:
function outer(){
var i = 1;
var func = new Function("console.log(i)");
func();//undefined
};
outer(); //i is not defined 构造函数是拿不到外层的变量的
func();// func is not defined
利用函数作用域
//局部变量(function name(){var a,b;})();
!function name(){};//加!浏览器就不会认为是函数申明