闭包:我个们可以用一个函数 去访问 另外一个函数的内部变量 的方式就是闭包
(自己的:子函数可以去访问父函数的局部变量)
内部变量 是 局部变量
- [x] 闭包的优点:不会产生局部变量,实现属性私有化
- 缺点:闭包中的数据会常驻内存,在不用的时候要删除掉否则会导致内存溢出
function b(){
var num=10;
function a(){
console.log(num);
return num+1;
}
return a; //返回的是a函数体
}
console.log(b) //返回的是b函数体
console.log(b()); //调用b函数 返回的是a函数体
var c=b(); //调用b函数,返回的是a函数体
var d=c(); //相当于是调用a函数 打印10 返回11给d
console.log(d); //打印d的值 11 如果删除16行, 此处打印的为undefined
function out(){
var a=0;
return function (){
a++;
alert(a);
}
}
var obj=out(); //执行一次outer函数 此时a=0 返回inner函数体
obj(); //调用一次inner函数,弹出1
obj(); //调用一次inner函数,弹出2
var obj1=out(); //执行一次outer函数 此时a=0 返回inner函数体
obj1(); //调用一次inner函数,弹出1
obj1(); //调用一次inner函数,弹出2
闭包传参
function fun(x){
return function(){
console.log(x); //子函数内部可以使用父函数的参数
}
}
var obj=fun(4); //执行一次fun(x)函数,返回函数体 相当于obj=function(){console.log(4)}
obj(); //注意不要在这传参,应该在上一行的fun()中传参,与定义函数时一致 此时打印出4
闭包传参:注意传的参数对应的是(undefined+任何数值都等于NaN)
function fun(x){
return function(y){
console.log(x+y); //子函数内部可以使用父函数的参数
}
}
var obj=fun(4); //传值給x 执行一次fun(x)函数,返回函数体 相当于obj=function(){console.log(4)}
obj(3); //传值給y
obj(); //此时y=undefined 4+undefined=NaN
闭包函数传参--小盒子左右走
var btn1=document.getElementById('btn1');
var btn2=document.getElementById('btn2');
var div=document.getElementById('div');
function move(speed){
return function(){
div.style.left=div.offsetLeft+speed+"px";
}
}
btn1.onclick=move(-5); //区别原来的click事件后面只能写函数名
btn2.onclick=move(5);
- [ ] 总结:什么时候使用闭包
- 类似点击事件,想传参数时
自己写的点击里,弹出li的index
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
</body>
</html>
<script type="text/javascript">
var ali=document.getElementsByTagName('li');
for (var i = 0; i < ali.length; i++) {
ali[i].onclick=function(num){
return function(){
alert(num);
}
}(i);
}
</script>