先简单总结一下:
1、涉及到改变数组值的时候,最好不要尝试用forEach。
2、当数组元素为基本数据类型时不可改变
3、当数组元素为引用类型时,有部分方法可改变
4、要在forEach里面改变数组,需要用array[index]或者item.xxx的方法来改变数组本身。
forEach--用于调用数组的每个元素,并将元素传递给回调函数,本身并不会改变数组。
但如果在循环中想改变数组应该怎么做呢?
直接修改是不行的,比如在下面这段代码中,表面上看着没有错误,item当下也确实变了,但实际上将最后的arr打印出来就会发现,arr实际上是没有改变的。
图1
但如果改成这样就可以生效。
图2
或者
图3
其实这中间涉及到引用类型和基本数据类型的差别
。首先我们先明确什么是基本数据和引用数据:基本数据类型和引用数据类型的区别主要为:基本数据类型是Number、String、Boolean、Null、 Undefined、Symbol,指存放在栈中的简单数据段,数据大小确定;而引用数据类型是object,指存放在堆内存中的对象,变量是保存在栈内存中的一个指针,并且每个空间大小不一样。
1、数组元素是引用类型数据时:
当我们使用forEach,每次我们看到的item并不是数组本身,而只是一个原数组对应对象的地址值。
这也是为什么我们使用item.XXX修改某一具体属性(如图2)或者arr[index](如图3)可以成功,而直接对item赋值(如图1)会失败。
如果把数组比作一栋房子,数组里的元素相当于房子里的家具,forEach返回的item相当于这栋房子的地址。
直接对item赋值的行为相当于给了一个新的地址,新的地址指向的是新房子,而不是旧房子(原数组),你对新房子做任何的“装修”,当然都不会影响到旧房子。而item.XXX或arr[index]相当于是直接找到房子里的某一个具体的家具,对其进行更换等行为,这样就会影响到房子。
2、数组元素是基本数据类型时:基本数据是没有地址的,forEach中只是将对应的值赋给了item,就好比下面的代码,不管如何修改item,都不会影响原数组a=2
b=a
b=3
console.log(a) //2
console.log(b) //3
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。