JavaScript高级-----10.函数进阶(递归)

6. 递归

6.1 什么是递归

<script>
    // 递归函数 : 函数内部自己调用自己, 这个函数就是递归函数
    var num = 1;

    function fn() {
        console.log('我要打印6句话');

        if (num == 6) {
            return; // 递归里面必须加退出条件
        }
        //return之后,下面两行代码也不再执行
        num++;
        fn();
    }
    fn();
</script>

6.2 利用递归求数学题

1. 求123...*n的阶乘

<script>
    // 利用递归函数求1~n的阶乘 1 * 2 * 3 * 4 * ..n
    function fn(n) {
        if (n == 1) {
            return 1;
        }
        return n * fn(n - 1);
    }
    console.log(fn(3));
    console.log(fn(4));
    // 详细思路 假如用户输入的是3
    //return  3 * fn(2)
    //return  3 * (2 * fn(1))
    //return  3 * (2 * 1)
    //return  3 * (2)
    //return  6
</script>

2. 求斐波那契数列

<script>
    // 利用递归函数求斐波那契数列(兔子序列)  1、1、2、3、5、8、13、21...
    // 用户输入一个数字 n 就可以求出 这个数字对应的兔子序列值
    // 我们只需要知道用户输入的n 的前面两项(n-1 n-2)就可以计算出n 对应的序列值
    function fb(n) {
        if (n === 1 || n === 2) {
            return 1;
        }
        return fb(n - 1) + fb(n - 2);
    }
    console.log(fb(3));
    console.log(fb(6));
</script>

6.3 利用递归:根据id返回对应的数据对象

<script>
    var data = [{
        id: 1,
        name: '家电',
        goods: [{
            id: 11,
            gname: '冰箱',
            goods: [{
                id: 111,
                gname: '海尔'
            }, {
                id: 112,
                gname: '美的'
            }, ]
        }, {
            id: 12,
            gname: '洗衣机'
        }]
    }, {
        id: 2,
        name: '服饰'
    }];
    // 我们想要做输入id号,就可以返回的数据对象
    // 1. 利用 forEach 去遍历里面的每一个对象
    function getID(json, id) {
        var o = {};
        json.forEach(function(item) {
            // console.log(item); // 2个数组元素
            if (item.id == id) {
                // console.log(item);
                o = item;
                // 2. 我们想要得里层的数据 11 12 可以利用递归函数
                // 里面应该有goods这个数组并且数组的长度不为 0 
            } else if (item.goods && item.goods.length > 0) {
                o = getID(item.goods, id);
            }

        });
        return o;
    }
    console.log(getID(data, 1));
    console.log(getID(data, 2));
    console.log(getID(data, 11));
    console.log(getID(data, 12));
    console.log(getID(data, 111));
</script>

6.4 浅拷贝和深拷贝

1. 浅拷贝

<script>
    // 浅拷贝只是拷贝一层, 更深层次对象级别的只拷贝地址.
    // 深拷贝拷贝多层, 每一级别的数据都会拷贝.
    var obj = {
        id: 1,
        name: 'andy',
        msg: {
            age: 18
        }
    };
    var o = {};
    for (var k in obj) {
        // k 是属性名   obj[k] 属性值
        o[k] = obj[k];
    }
    console.log(o);
    o.msg.age = 20;
    console.log(obj.msg.age);//20
</script>

对于对象级别的数据,浅拷贝只拷贝地址:将obj拷贝给o的时候,o里面msg拷贝的只是地址,让o和obj的msg指向了同一个地址,那么其中一个msg改变必定会影响另一个msg

<script>
    // 浅拷贝只是拷贝一层, 更深层次对象级别的只拷贝引用.
    // 深拷贝拷贝多层, 每一级别的数据都会拷贝.
    var obj = {
        id: 1,
        name: 'andy',
        msg: {
            age: 18
        }
    };
    var o = {};
    Object.assign(o, obj);//这种方法实现浅拷贝更简单  将obj拷贝给o
</script>

2. 深拷贝

<script>
    // 深拷贝拷贝多层, 每一级别的数据都会拷贝.
    var obj = {
        id: 1,
        name: 'andy',
        msg: {
            age: 18
        },
        color: ['pink', 'red']
    };
    var o = {};
    // 封装函数 
    function deepCopy(newobj, oldobj) {
        for (var k in oldobj) {
            // 判断我们的属性值属于那种数据类型
            // 1. 获取属性值  oldobj[k]
            var item = oldobj[k];
            // 2. 判断这个值是否是数组
            if (item instanceof Array) {
                newobj[k] = [];
                deepCopy(newobj[k], item)
            } else if (item instanceof Object) {
                // 3. 判断这个值是否是对象
                newobj[k] = {};
                deepCopy(newobj[k], item)
            } else {
                // 4. 属于简单数据类型
                newobj[k] = item;
            }
        }
    }
    deepCopy(o, obj);
    console.log(o);

    var arr = [];
    console.log(arr instanceof Object); //true  数组也是一个对象  所以上述判断条件,先判断是否是数组再判断是否为 对象
    o.msg.age = 20;
    console.log(obj.msg.age); //18  不被修改
</script>
posted @ 2020-03-02 17:35  deer_cen  阅读(358)  评论(0编辑  收藏  举报