Object assgin拷贝问题?

let obj1={a:1}
let obj2={b:{data:1}}
Object.assign(obj1,obj2)
console.log('obj1',obj1);
obj1.b=10

为什么这段代码会输出

{
    "a": 1,
    "b": 10
}

而不是

{
    "a": 1,
    "b": {
        "data": 1
    }
}

呢?

阅读 8k
avatarAI BotBETA
### 回答

`Object.assign()` 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。

在你的代码中:

let obj1 = {a:1};
let obj2 = {b:{data:1}};
Object.assign(obj1, obj2);


此时,`obj2` 中的属性 `b` 被复制到 `obj1` 中。但是,这里需要注意的是,`b` 是一个对象 `{data: 1}`,而 `Object.assign()` 是浅拷贝(shallow copy),即它只复制了对象的引用,而不是对象本身。因此,`obj1.b` 和 `obj2.b` 指向同一个对象 `{data: 1}`。

然而,接下来的代码:

obj1.b = 10;


这行代码并没有修改 `obj1.b` 所指向的对象的内容,而是直接改变了 `obj1.b` 的引用,使其指向了一个新的值 `10`。因此,`obj1` 和 `obj2` 的 `b` 属性不再共享同一个引用。

所以,当你打印 `obj1` 时:

console.log('obj1', obj1);


输出结果为:

{

"a": 1,
"b": 10

}


而不是:

{

"a": 1,
"b": {
    "data": 1
}

}


因为 `obj1.b` 的引用已经被改变为 `10`,而 `obj2.b` 仍然指向 `{data: 1}`。
4 个回答

这里的主要问题不在于 Object.assign,而在于 console.log,

当你点开这个 console.log 的记录时,就能看到旁边有一个叹号的图标,放上去就能看到提示了。

image.png

简单的说,对于对象而言 console.log 打印的实际是一个变量的引用指向,后续代码对对象值的改变会影响到最终看到的结果,要想避免这个问题,对于简单对象,可以使用 JSON 化进行处理。

console.log

image.png

Object.assign()属于浅拷贝,即使你在操作obj1之前打印obj1,但是他是对象,操作后还是会影响输出的值,如果你不想使用浅拷贝,可以使用JSON.parse(JSON.stringfy())或者lodash的cloneDeep()来做深拷贝,则不会影响obj1的值

新手上路,请多包涵

image.png
debugger一下就知道了,到log的时候还是一个对象。但是浏览器的log输出是一个引用,你点开对象的时候会去拿最新的值,这时候就变成10了

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