老师帮我看一下,为什么数组里面的数组没有被推入新数组。

老师帮我看一下,为什么数组里面的数组没有被推入新数组。

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>深克隆</title>

</head>

<body>

    <script>

        //对原数组进行深克隆处理

        var arr1 = [1,2, 3, 4, 5, 6, 7, [8, 9, [10, 11]]];

        //递归

        function deepClone(arr) {

            //创建一个空数组接收推入的数据

            var arr2 = [];

            //先对原数组进行遍历

            for(var i = 0; i < arr.length; i ++) {

                //对遍历到的项进行判断

                if(Array.isArray(arr[i])) {

                    deepClone(arr[i]);

                } else {

                    arr2.push(arr[i]);

                }

            }

            return arr2;

        }

        var arr3 = deepClone(arr1);

        console.log(arr3);

    </script>

</body>

</html>


//老师,您看一下这个位置我不理解,for循环里面先判断类型,如果是数组的话,会进入递归,调用函数本身。以此题为例,[1,234567, [89, [1011]]]当数组判断至 [89, [1011]]时,会把 [89, [1011]]调用函数,重新遍历后判断类型,遇到8和9时,此时数据类型为普通,这时是不是可以直接执行else里面的内容了,把8和9推入arr2,然后到  [1011]时又重新递归调用函数,对类型进行判断,这是又把10和11推入arr2数组了,我是这样理解的,老师请详细的给我讲解一下,谢谢

 for(var i = 0i < arr.lengthi ++) {

                //对遍历到的项进行判断

                if(Array.isArray(arr[i])) {

                    deepClone(arr[i]);

                } else {

                    arr2.push(arr[i]);

                }

            }


//我写的代码得出的结果是        

[

    1,

    2,

    3,

    4,

    5,

    6,

    7

]


正在回答 回答被采纳积分+1

登陆购买课程后可参与讨论,去登陆

1回答
好帮手慕慕子 2022-04-22 15:50:47

同学你好,对于你的问题解答如下:

1、因为for循环中,判断类型为数组后,在调用deepClone方法时,没有将返回结果添加到arr2中,导致数组里的数组没有被推入新数组中。

建议修改:结合push方法将数组添加到新数组中

https://img1.sycdn.imooc.com//climg/626259f3093aad9006410393.jpg

2、同学理解是对的,代码的详细执行过程可以参考如下解析:

  • 第一次调用函数deepClone,传入参数arr1,函数内部声明新数组arr2

    • 第一次循环,1是基本数据类型,不符合Array.isArray(arr[i])条件,会执行else语句,把1推入到arr2数组中。

    • 第二次循环,2是基本数据类型,不符合Array.isArray(arr[i])条件,会执行else语句,把2推入到arr2数组中。

    • 依次类推······

    • 经过7次循环,arr2数组中的值是[1,2,3,4,5,6,7].

    • 第五次循环,[8,9[10,11]]是一个数组,符合Array.isArray(arr[i])条件,会再次调用deepClone函数(这是第二次调用deepClone函数),需要等待第二次调用结束,第一次调用deepClone才会继续往下执行代码。

  • 第二次调用deepClone函数,[8,9[10,11]]作为deepClone函数的参数,函数内部声明新数组arr2

    • 第一次循环,8是基本数据类型,不符合Array.isArray(arr[i])条件,会执行else语句,把8推入到arr2数组中。

    • 第二次循环,9是基本数据类型,不符合Array.isArray(arr[i])条件,会执行else语句,把9推入到arr2数组中。

    • 第三次循环,[10,11]是一个数组,符合Array.isArray(arr[i])条件,会再次调用deepClone函数(这是第三次调用deepClone函数),需要等待第三次调用结束,第二次调用deepClone才会继续往下执行代码。

  • 第三次调用deepClone函数,[10,11]作为deepClone函数的参数,函数内部声明新数组arr2

    • 第一次循环,10是基本数据类型,不符合Array.isArray(arr[i])条件,会执行else语句,把10推入到数组arr2中。

    • 第二次循环,11是基本数据类型,不符合Array.isArray(arr[i])条件,会执行else语句,把11推入到数组arr2中。

    • 循环结束,此时arr2 = [10, 11],即第三次调用返回结果为[10, 11]

  • 第三次调用结束,继续执行第二次的调用,第三次deepClone(arr[i])的返回值[10, 11],被添加到了第二次创建的arr2中。注意第二次的arr2值为[8,9],所以arr2.push(deepClone(arr[i]));执行之后,arr2的值为[8,9, [10, 11]]。

  • 第二次调用结束,继续执行第一次的调用,第二次deepClone(arr[i])的返回值[8,9, [10, 11]],被添加到了第一次创建的arr2中。注意第一次的arr2值为[1,2,3,4,5,6,7],所以arr2.push(deepClone(arr[i]));执行之后,arr2的值为[1,2,3,4,5,6,7,8,9, [10, 11]]。

祝学习愉快~

  • 提问者 dy12369 #1

    您好老师,是不是这样理解。在数组遍历时遇到数组包含数组时,数组每次递归调用新函数时,都是重新赋值一个数组来接受此个数组遍历的值,就算全部遍历后,包含在里面的数组在克隆后还是以数组的形式被推入到了最开始的接收数组,而不会直接把值推入最开始的数组。

    //例子:[1,2,3,4,5,6,7,8,9, [10, 11]],在经过三次调用函数后,被推入arr2中的形式还是以数组的形式推入,而不是直接推入8,9,10,11这四个数字。


    还有一个疑问:既然下面重新声明了一个数组接收,为什么在这里还要返回一个结果

    https://img1.sycdn.imooc.com//climg/6262605509a3218d06470495.jpg

    2022-04-22 16:00:01
  • 好帮手慕慕子 回复 提问者 dy12369 #2

    问题解答如下:

    1、理解是对的

    2、因为要结合递归去调用deepClone函数,实现对数组中的数组进行深克隆,所以需要设置返回值,将deepClone函数调用后的结果添加到数组中,实现深克隆。

    截图中的写法是直接将数组中的数组添加到新数组中,无法实现深克隆,示例:改变arr3中的数组项,arr1中的内容也会跟着改变

    https://img1.sycdn.imooc.com//climg/626263ab09640fa215310847.jpg

    祝学习愉快~

    2022-04-22 16:16:56
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师