JavaScript数组赋值浅谈

开头,说明一下两个常用的概念:深拷贝和浅拷贝

1.浅拷贝: 将原对象或原数组的引用直接赋给新对象,新数组,新对象/数组只是原对象的一个引用
2.深拷贝: 创建一个新的对象和数组,将原对象的各项属性的“值”(数组的所有元素)拷贝过来,是“值”而不是“引用”
关于深拷贝和浅拷贝的详解,可访问此博客:https://www.cnblogs.com/penghuwan/p/7359026.html#_label0_0
由上述概念,我们可以知道,如下代码的结果:
1 let arr = [1,13,16,5,8];
2 let newArr = arr;
3 newArr.sort((a,b)=>a-b);
4 console.log(arr) // [1,5,8,13,16]

显然,新数组newArr只是原数组arr的一个引用,在对newArr排序时,数组对象arr也被改变了。

如果想要不改变原数组,就需要用到深拷贝。代码如下:

1 let arr = [1,13,16,5,8];
2 let newArr = new Array(arr);
3 newArr.sort((a,b)=>a-b);
4 console.log(newArr) // [1,5,8,13,16]
5 console.log(arr) // [1,13,16,5,8]

 说到这里,似乎已经对js数组传递有了全面的了解,但是最近在知乎看到这样一段代码:

var a = [1,2,3];
var b = a;
a = [4,5,6];
alert(b);  //[1,2,3]

 

这样的结果就有点令人奇怪了,数组对象b既然是a的一个引用,那么改变a的同时,b理所应当发生变化呀。然而事实却是b并没有发生改变。

仔细深究,便可发现问题所在。关于JavaScript是按值传递还是按引用传递,推荐文章:https://zhuanlan.zhihu.com/p/24080761

首先需要说明无论是a还是b,其实都是数组实例 [1,2,3] 的引用吗,当把a赋值给b时,其实只是让b指向a所指向的数组实例。

因此,a=[4,5,6]不过是将a指向了新的数组实例,对b并没有什么影响。图解如下:

而之前谈到的数组排序,将arr的引用赋值给newArr之后,对newArr进行排序,实际上是通过引用地址,将原数组对象或者说原数组实例改变了,因此引用arr也发生了改变。

谈论至此,以上问题均可以合理解释。

 

此番论述为网上查阅他人的博客和见解,再结合自己的理解所得结论,如有不对,请指出。

2019-07-17

 

实践运用笔记

在vue中使用v-bind绑定js数组中的数据时,当使用数组下标(如:array[1] = 5)修改数组数据时,发现v-bind绑定的数组数据并未修改,而在控制台打印出数组,发现数组已经修改了。根据上述js数组特性,我猜测,通过数组下标修改仅仅修改了该数组的一个引用,而对数组实例并没有影响。测试:使用array对象的方法(如:splice)修改该数组,发现v-bind绑定的数组数据也修改了,这似乎证明了该结论。在本次实践中,我通过splice方法对指定位置进行元素替换。

posted @ 2019-07-17 16:27  linktodream  阅读(1613)  评论(0编辑  收藏  举报