今天工作时碰到一个需求,有两个数组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. alert弹出框 弹出窗口 ----sweetAlert

    推荐一款好用的alert,下面地址是demo,很直观的看到效果,wap可以使用 http://www.dglives.com/demo/sweetalert-master/example/   < ...

  2. 微信小程序跳转以及跳转的坑

    一.首先小程序的跳转方法有一下几种 js控制跳转 // 保留当前页面,跳转到应用内的某个页面 wx.navigateTo({ url: '../blueberry/blueberry' }); // ...

  3. webstorm for mac

    mac上使用webstrom,破解的方法 参见博客:Webstorm 破解2016.1 for mac 上面的说明有点问题,博主的写的有点问题.应该是1.先打开到注册页面:2.再关闭webstrom; ...

  4. 从输入url到页面展示出来经历了哪些过程

    本文只是一个整理向的随笔,以个人思路来简化的同时进行适当的拓展,如有错误,欢迎指正. 1.输入网址.  此时得到一个url 2.域名解析 整个过程都是dns系统在发挥作用,它的目的是将域名和ip对应起 ...

  5. ESP32 开发笔记(十二)LittlevGL 添加自定义字体和物理按键

    LittlevGL 添加自定义字体获取字库 ttf 文件可以从一些网站上获取字库文件,比如请注意字体许可证 生成源文件使用 LittlevGL 提供的字库文件转换工具,将 ttf 字库文件转换为源文件 ...

  6. Bamboo Django Celery定时任务和时间设置

    1.Celery加入定时任务 Celery除了可以异步执行任务之外,还可以定时执行任务.在实例代码的基础上写个测试方法: 1 #coding:utf-8 2 from celery.task.sche ...

  7. 第1章 面向对象的JavaScript

    针对基础知识的每一个小点,我都写了一些小例子,https://github.com/huyanluanyu1989/DesignPatterns.git,便于大家理解,如有疑问,大家可留言给我,最近工 ...

  8. js中二维数组的创建方法 2017-04-04 14:50 120人阅读 评论(0) 收藏

    法一:var myarr=[[0,1,2],[1,2,3]]; 将[0,1,2]看做原来的0,将[1,2,3]看做原来的1,而二者又分别为子数组 如myarr[0][1]=1,myarr[1][1]= ...

  9. 继续聊WPF——Expander控件(2)

    <Window x:Class="Expander_Sample2.Window1" xmlns="http://schemas.microsoft.com/win ...

  10. C#学习笔记_01_基础内容

    01_基础内容 进(位)制 十进制:逢10进1,数字由0-9组成: 二进制:逢2进1,数字由0-1组成: 八进制:逢8进1,数字由0-7组成: 十六进制:逢16进1,数字由0-9和a-f组成: 进制转 ...