js forEach遍历修改对象的问题

        const arr1 = [
            { id: 1, value: 1 },
            { id: 2, value: 2 },
            { id: 3, value: 3 },
            { id: 4, value: 4 },
            { id: 5, value: 5 },
        ]

        arr1.forEach((item, index) => {
            if (item.id === 1) {
                item.value *= 10   // 修改成功
            }
        })

        arr1.forEach((item, index) => {
            if (item.id === 1) {
                item = {id:6,value:6}  // 无法修改
            }
        })

为什么在使用forEach遍历修改对象数组的某项的属性值的时候,就能够修改成功呢

阅读 8.9k
6 个回答

对于第一种情况,可以理解为

const it = { value: 10 };
const item = it;
item.value = 11;
console.log(it);   // item 和 it 指向同一个对象,所以对象的属性 value 被修改了

第二种情况

const it = { value: 10 };
let item = it;           // 这里 item 和 it 是指向同一个对象
item = { value: 6 };     // 但这里 item 指向了新的对象(直接赋值),而 it 还是指向的原来那个对象
console.log(item, it);   // 所以 it 还是 { value: 10 },而 item 已经是 { value: 6 } 了

因为对象是引用,你相当于只改了形参的指针,没有改到原数组的指针

// 方法1: Object.assign
arr1.forEach((item, index) => {
    if (item.id === 1) {
        Object.assign(item, { id:6, value:6})
    }
})
// 方法2: 改指针
arr1.forEach((item, index, arr) => {
    if (item.id === 1) {
        arr[index] = { id:6, value:6}
    }
})

你要改的话,这样也可以。

arr1.forEach((item, index) => {
    if (item.id === 1) {
        Object.assign(item, {id:6,value:6})
    }
})

对象都是引用,数组(arr1)遍历的时候给的是引用(item),
可以修改引用(item)里面的值,但你不能直接换掉引用(item={}),因为数组(arr1)还保留着引用。
如果你想换掉引用,必须找原先的数组里面替换掉(arr1[index]={})。

forEach 修改源数据的最好的方式应该是这样

arr1.forEach((item, index,arr) => {
    if (item.id === 1) {
        arr[index] = {id:6,value:6}
    }
})

javascript没有引用传递,均为按值传递

比如像php就有引用传递

<?php
function test(&$a) {
  $a = 20;
}

$a = 10;
test($a);
echo $a; // 输出 20

上面的php代码,如果把参数里的&符号去掉,那就变成按值传递了

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题