今天工作时碰到一个需求,有两个数组arrayChild, arrayFather, 要求:

1、往数组arrayChild中放入一个元素;

2、将当前的数组arrayChild放入arrayFather中;

3、清空数组arrayChild,将一个新元素放进去;

4、将放了新元素的arrayChild放入数组arrayFather中。

刚开始是这么写的:

const arrayChild = [];
const arrayFather = []; arrayChild.push(0, 1);
arrayFather.push(arrayChild); arrayChild.splice(0); arrayChild.push(3, 4);
arrayFather.push(arrayChild); console.log(`arrayFather = ${arrayFather}`);
预想结果是:
arrayFather = [[0, 1], [3, 4]];
实际结果:
arrayFather = [[3, 4], [3, 4]];

为什么呢?向公司老司机请教,才知道原来创建一个数组时,会在内存中开辟一块堆内存A,我的arrayChild是在另一块栈内存中存入了指向堆内存A的地址,所以使用const声明的数组,还可以继续向数组内添加东西。在第一步,arrayFather.push(arrayChild),也是将arrayFather指向了arrayChild指向的堆内存A,然后splice是清除arrayChild中的数据,就是将堆内存A中的数据全部清除,所以这时arrayFather和arrayChild都是空的。这时再往arrayChild中添加新数据,那么arrayFather = arrayChild = [3, 4], 然后arrayFather又push了一次arrayChild,所以最后arrayFather = [[3, 4], [3, 4]]

那想要实现需求怎么办呢?可以用这种方法:

let arrayChild = [];
const arrayFather = []; arrayChild.push(0, 1);
arrayFather.push(arrayChild); arrayChild = []; arrayChild.push(3, 4);
arrayFather.push(arrayChild); console.log(`arrayFather = ${arrayFather}`);
预想结果是:
arrayFather = [[0, 1], [3, 4]];
实际结果:
arrayFather = [[0, 1], [3, 4]];

这里的arrayChild = []就是重新开辟一片内存了,所以原来的值还会存在,相当于:

1、首先分配了一块内存(数组的值存放在堆中,索引存放在栈中),存了个数组[0, 1],索引是arrayChild

2、将arrayFather(前两个地址指针)指向这块堆内存

3、另外分配一块新内存,存了数组[3, 4],把索引arrayChild重新指向这里

4、将新内存的地址存入arrayFather(的arrayFather[2]和arrayFather[3])中,因为原先的arrayChild的值还在被arrayFather引用,所以这块内存不会被回收,所以最终的目的达成。

综上所述,问题的根源在于对数组的本质不了解。新建数组,就是新分配一块堆内存存放数组的值。堆内存的地址存放在一块栈内存中,组成数组的索引。

JS中数组的一些笔记的更多相关文章

  1. js中数组去重的几种方法

    js中数组去重的几种方法         1.遍历数组,一一比较,比较到相同的就删除后面的                 function unique(arr){                 ...

  2. JavaScript -- 时光流逝(二):js中数组的方法

    JavaScript -- 知识点回顾篇(二):js中数组的方法 1. 数组 (1)定义数组,数组赋值 <script type="text/javascript"> ...

  3. php和js中数组的总结

      php中数组的表示方法:array()或者[] js中数组的表示方法:new array()或者[] 一.php中初始化命名数组 在PHP中声明数组的方式主要有两种:一是应用array()函数声明 ...

  4. JS中数组的介绍

    一.数组: 一组数据的集合: 二.JS中数组的特点: 1.数组定义时无需指定数据类型: 2.数组定义时可以无需指定数组长度: 3.数组可以存储任何类型的数据: 4.一般是相同的数据类型: 三.数组的创 ...

  5. js中数组增删查改unshift、push、pop、shift、slice、indexOf、concat、join

    js中数组增删查改unshift.push.pop.shift.slice.indexOf.concat.join

  6. js中数组如何使用

    js中数组如何使用 一.总结 一句话总结:new Array()和[]两种方法都可以创建数组. 二.js中创建数组,并往数组里添加元素 数组的创建 var arrayObj = new Array() ...

  7. js中数组方法大全

    js数组方法大全 一:前言 我们在学到js中数组的时候,我们会接触到js中数组的一些方法,这些方法对我们来说,可以很遍历的达到我们想要的结果,但是因为方法比较多,有些方法也不常用,可能会过一段时间就会 ...

  8. js中数组去重方法及性能对比

    js中数组的 数组去重 常用的数组去重方法以及效率分析: 首先我们先构建一个数组,主要是用于进行去重实验,我们主要实验的量级为1000,10000,100000,500000.具体的生成数组的方法如下 ...

  9. js中数组扁平化处理

随机推荐

  1. Fedora Atomic Host 使用中的几个坑

    做成U盘启动:必须用配套工具写U盘,否则安装时各种timeout Cockpit中文页面会导致登录后页面空白的bug,解决办法是更改浏览器首选语言 没有yum,无法下载网页浏览器w3m,Pydio c ...

  2. java中为什么不允许类多重继承,却允许接口多重继承

    首先看下面这一段代码:(底下有热心网友更正,jdk1.8之后情况确实有点变化,等改天有空继续更) interface a{ void b();}interface a1 extends a{ void ...

  3. eas之获取单据编码规则

    //获取单据编码规则  /*** @Title: getNumber* @Description: TODO(获取单据编码规则)*               <p>* @date 201 ...

  4. C#第十五节课

    函数复习 using System;using System.Collections.Generic;using System.Linq;using System.Text;using System. ...

  5. Java8自定义条件让集合分组

    /** * 将一个指定类型对象的集合按照自定义的一个操作分组: 每组对应一个List.最终返回结果类型是:List<List<T>> * * @param <T> ...

  6. Java中==和equals()的区别

  7. JDK环境变量设置(linux)

    1.下载jdk1.8版本软件包 2.解压 tar -zxvf jdk1.8.tar.gz mv jdk1.8 /usr/local/ 3.添加环境变量 vim /etc/profile 在文件底部加入 ...

  8. Django-xadmin+django-import-export导入导出的实现

    转载自:https://blog.csdn.net/zcyuefan/article/details/77748850 1. 需求vs现状1.1 需求要求做一个ERP后台辅助管理的程序,有以下几项基本 ...

  9. 关于git修改和查看用户名邮箱

    git 查看/修改用户名.密码 查看用户名和邮箱地址: $ git config user.name $ git config user.email 修改用户名和邮箱地址: $ git config ...

  10. ssh的tunnel设置+autossh设置

    tunnel设置 一.说明 用于通过ssh转发数据 二.设置 编辑ssh server的'2Fetc/ssh/sshd_config 加入下面: #反向遂道 GatewayPorts  yes #正向 ...