局部变量是在函数中,函数使用结束后,局部变量就会被自动的释放
闭包后,里面的局部变量的使用作用域链就会被延长
1、闭包
闭包的概念:一个函数A中存在另外一个函数B,函数B可以访问函数A中的数据或变量
闭包的模式:分为两种:函数模式闭包 和 对象模式闭包
闭包的作用:缓存数据,延长作用域链
闭包的优缺点:缓存数据,优点也是缺点,因为局部变量没有及时被释放
总结:如果想要缓存数据,就把这个数据放在外层的函数和里层的函数的中间位置
function f1() { var num = 10; return function() { num++; console.log(num); } } var fn=f1(); //f1函数中有返回值,所以存放在变量ff中 fn(); //因为返回值是一个函数,需要再次调用 此时输出结果是 num=11 fn(); // num=12 再次调用 fn 执行的是 返回值中的函数,所以会在上一次调用 fn 的基础上 num+1 //如果多次直接调用 f1 函数,每次调用时 num的初始化值都是10 f1()(); //num=11 f1()(); //num=11
案例:
//点赞案例 计数 <input type="button" value="赞(1)"> <input type="button" value="赞(1)"> <input type="button" value="赞(1)"> <input type="button" value="赞(1)"> <script> function my$(tar) { return document.getElementsByTagName(tar); } var objs = my$("input"); function getValue() { var value = 2; return function() { this.value = "赞(" + value++ + ")"; } } for (var i = 0; i < objs.length; i++) { objs[i].onclick = getValue(); } </script>
2、 沙箱
沙箱概念:环境,黑盒,在虚拟环境中模拟真实世界。
自调用函数 (function(){}()); 也是沙箱(主要为了避免命名冲突)
var str="自调用函数外的内容"; str.substr(3); //函数外的内容 (function(){ // console.log(str); //此时str=undefined;因为自调用函数中有str,如果自调用函数中没有 str 则str=自调用函数外的内容 var str="冰果消消消"; str.substr(2); //消消消 }()); //此时str不是有命名冲突的问题,因为,宾果消消消在沙箱(自调用函数)中存在。
3、递归
递归概念:函数中调用自己 ,递归要有结束条件,否则就是死循环,一般用于遍历
效率低,一般不使用
//使用递归的方式计算n以内的和:4==>4+3+2+1 function getSum(n){ if(n==1){ return 1; } return n+getSum(n-1) } //代码执行过程是:先由外到内,再由内到外,并不是直接输出 //4+getSum(3),先不计算结果,先执行getSum(3)==>3+getSum(2),先不计算,等待,先执行getSum(2)==>2+getSum(1),等待,getSum(1),return 1; //此时 getSum(2)=2+1; //getSum(3)=3+2+1; //getSum(4)=4+3+2+1;