闭包,沙箱,递归

局部变量是在函数中,函数使用结束后,局部变量就会被自动的释放
闭包后,里面的局部变量的使用作用域链就会被延长

 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;

 

posted @ 2020-03-29 12:47  晴天宝宝i  阅读(193)  评论(0编辑  收藏  举报