闭包与递归

57 阅读2分钟

闭包

什么是闭包?

变量作用域,变量根据作用域的不同分为两种:全局变量和局部变量

  1. 函数内部可以使用全局变量
  2. 函数外部不可以使用局部变量
  3. 当函数执行完毕,本作用域内的局部函数会销毁

闭包指有权范文另一个函数作用域中变量的函数,简单的理解就是,一个作用域可以访问另外一个函数内部的局部变量.

function fn(){
    let num=10;
    function fun(){
        console.log(num);
    }
    fun();
}
fn();

闭包的作用

闭包的主要作用:延伸了变量的作用范围

// 闭包计算打车费案例
let car=(function(){
    let start=13; // 起步价 局部变量
    let total=0; // 总价 局部变量
    return {
        price:function(n){
            if(n<=3){
            total=start;
            console.log(total);
            }else{
            total=start+(n-3)*5;
            console.log(total);
            }
        },
        // 拥堵之后的费用
        yd:function(flag){
            return flag? total+10:total;
        }
    }
})();
car.price(5);
let total= car.yd(true);
console.log(total);

递归

什么是递归?

如果一个函数在内部可以调用其本身,那么这个函数就是递归函数

简单理解: 函数内部自己调用自己,这个函数就是递归函数

递归函数的作用和循环效果一样

由于递归很容易发生"栈溢出"错误,所以必须要加退出条件return

let num=1;
function fn(){
    console.log("打印"+num+"次");
    if(num==6){
        return; // 递归里面必须有退出条件
    }
    num++;
    fn();
}
fn();

递归的使用场景

递归的应用场景: 菜单树,求和,深拷贝和浅拷贝...

// 深拷贝案例

var obj = {

       id: 1,

       name: 'and',

       msg: {

           age: 18

       },

       color: ['pink', 'red']

};

var o = {};

// 封装函数

function add(newobj, oldobj) {

// 遍历对象

   for (k in oldobj) {

// oldobj[k] 是旧对象的属性值

       var itme = oldobj[k];

// 判断itme是不是数组 因为数组也属于对象 所以数组要写在对象的前面

       if (itme instanceof Array) {

// 如果是数组那就创建一个新的数组 newobj[k]=o.k (因为k是旧数组的属性名)

           newobj[k] = [];

// 递归调用函数

           add(newobj[k], itme);

       }

// 判断是不是对象

       else if (itme instanceof Object) {

// 如果是对象那就创建一个新的对象 newobj[k]=o.k (因为k是旧数组的属性名)

           newobj[k] = {};

// 调用递归函数

           add(newobj[k], itme);

}

// 如果不是数组也不是对象 那就让 newobj[k]=itme

       else {

           newobj[k] = itme;

       }

   }

}

add(o, obj);

console.log(o);