问答

JS中forEach究竟能不能改变数组的值?

作者:admin 2021-04-17 我要评论

let arr = [ { name: '1', id: '1' },{ name: '2', id: '2' },{ name: '3', id: '3' }]arr.forEach(list={ if(list.name==='2'){ list = {a: 'hee'} //list.name...

在说正事之前,我要推荐一个福利:你还在原价购买阿里云、腾讯云、华为云服务器吗?那太亏啦!来这里,新购、升级、续费都打折,能够为您省60%的钱呢!2核4G企业级云服务器低至69元/年,点击进去看看吧>>>)
let arr = [
  {   name: '1',
      id: '1'
  },{ name: '2',
      id: '2'
  },{   name: '3',
      id: '3'
  }
]

arr.forEach(list=>{
  if(list.name==='2'){
    list = {a: 'hee'}
    //list.name = {a: 'hee'} 结果可以改变原数组
  }
})
console.log(arr)

这个是MDN的介绍

image.png

###

不改变原数组指的是不对原数组重新赋值,但你数组里的值是可以随便改的,反过来讲也就是说改变原数组的意思是对原数组变量重新赋值的意思,举个例子:reverse是对数组进行翻转,它返回一个翻转后的数组,但与此同时原数组其实也改变了

这就是MDN描述的所谓改变的意思

reverse 方法颠倒数组中元素的位置,改变了数组,并返回该数组的引用。

再举个例子比如map,它同样返回处理后的数组,但它不改变原数组,也就是它其实返回的是一个新数组,而不是对原数组进行操作

###

1、基本数据类型 -> 死都改不动原数组!

const array = [1, 2, 3, 4];
array.forEach(ele => {
ele = ele * 3
})
console.log(array); // [1,2,3,4]

2、引用类型 -> 类似对象数组可以改变

const objArr = [{
    name: 'wxw',
    age: 22
}, {
    name: 'wxw2',
    age: 33
}]
objArr.forEach(ele => {
    if (ele.name === 'wxw2') {
        ele.age = 88
    }
})
console.log(objArr); // [{name: "wxw", age: 22},{name: "wxw2", age: 88}]

3、那引用类型 -> 改变整个单次循环的item? ->不行

const changeItemArr = [{
    name: 'wxw',
    age: 22
}, {
    name: 'wxw2',
    age: 33
}]
changeItemArr.forEach(ele => {
    if (ele.name === 'wxw2') {
        ele = {
            name: 'change',
            age: 77
        }
    }
})
console.log(changeItemArr); // [{name: "wxw", age: 22},{name: "wxw2", age: 33}]

4、终极方法!

// 基本类型
const numArr = [33,4,55];
numArr.forEach((ele, index, arr) => {
    if (ele === 33) {
        arr[index] = 999
    }
})
console.log(numArr);  // [999, 4, 55]

// 引用类型
const allChangeArr = [{
    name: 'wxw',
    age: 22
}, {
    name: 'wxw2',
    age: 33
}]
allChangeArr.forEach((ele, index, arr) => {
    if (ele.name === 'wxw2') {
        arr[index] = {
            name: 'change',
            age: 77
        }
    }
})
console.log(allChangeArr); // // [{name: "wxw", age: 22},{name: "change", age: 77}]

总结一下
基本类型我们当次循环拿到的ele,只是forEach给我们在另一个地方复制创建新元素,是和原数组这个元素没有半毛钱联系的!所以,我们使命给循环拿到的ele赋值都是无用功!

专业的概念说就是:JavaScript是有基本数据类型与引用数据类型之分的。对于基本数据类型:number,string,Boolean,null,undefined它们在栈内存中直接存储变量与值。而Object对象的真正的数据是保存在堆内存,栈内只保存了对象的变量以及对应的堆的地址,所以操作Object其实就是直接操作了原数组对象本身。

forEach 的基本原理也是for循环,使用arr[index]的形式赋值改变,无论什么就都可以改变了。

###

题主先要区分值类型引用类型

不改变原数组,不是不可以改变数组里某个引用对象的某个属性。

版权声明:本文转载自网络,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。本站转载出于传播更多优秀技术知识之目的,如有侵权请联系QQ/微信:153890879删除

相关文章
  • nginx响应速度很慢

    nginx响应速度很慢

  • 点击选中的多选框,会在已选那一栏显示

    点击选中的多选框,会在已选那一栏显示

  • PHP 多态的理解

    PHP 多态的理解

  • 关于C语言中static的问题

    关于C语言中static的问题

腾讯云代理商
海外云服务器