请教一个 js 的问题

let a = {
  a: 1,
  b: 2,
  c: 3
}
let b = a

b.a = 2

console.log(a.a) // 2

let c = JSON.parse(JSON.stringify(b))
c.a = 4

console.log(a.a) // 2

/*
** 请问这是为什么??
*/
  • JavaScript

    JavaScript 一种动态类型、弱类型、基于原型的直译式脚本语言,内置支持类型。它的解释器被称为 JavaScript 引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在 HTML 网页上使用,用来给 HTML 网页增加动态功能。

    585 引用 • 1097 回帖 • 770 关注
  • Q&A

    提问之前请先看《提问的智慧》,好的问题比好的答案更有价值。

    1680 引用 • 11051 回帖 • 581 关注
9 回帖
请输入回帖内容...
  • 88250
    • b 是 a 的引用,所以修改 b 的字段实际上会影响 a
    • c 是反序列化构造的新对象,不影响原对象引用

    —— 来自 Java 程序员的观点

    2 回复
  • Eddie 1

    你们捉的是周树人。跟我鲁迅有啥关系?

  • lzh984294471

    解释没毛病。

  • zhujie 1

    前端来解释一下,a 是对象,直接赋值会有引用关系,所以 a 和 b 指向同一个内存地址,会相互影响。

    通过 JSON 操作后的值赋给 c,相当于实现了一个对象的深拷贝。所以 c 和 a,b 直接没有引用关系。

  • hevi1991

    b 是 a 的浅复制,引用关系。

    c 是 b 被 JSON 序列化后的新对象,深拷贝。因为用的是 js 所以可以直接给 JSON 对象赋值。

  • wizardforcel

    无论什么格式,解析的时候肯定要创建新对象,不管你是 JSON,XML 还是 CSV,都这样。

    一种情况例外,就是用 require 加载 JSON,因为模块是单例。

    1 操作
    wizardforcel 在 2020-05-09 14:34:40 更新了该回帖
  • Rabbitzzc 1

    第一种输入是因为引用关系,第二种是因为序列化以后生成了新的对象,因此修改 b.a,不会更改 a.a,此时指向的地址是不同的。

    【注意】:这里的 a 对象属性都不是对象,为基础类型;如果 a.a 为对象,此时 JSON.xxx 对 a.a 也是浅拷贝的

    可以看看 js deepcopy 的源码

  • zhouwenhao529

    解析没毛病

请输入回帖内容 ...