为什么Object.assign会修改原对象,甚至对象被冻结后仍生效?
问题原因解析
1. 原始对象被修改的核心原因
Object.assign的语法规则是Object.assign(target, ...sources),第一个参数是目标对象,方法会把后续所有源对象的可枚举属性拷贝到目标对象上,最终返回目标对象本身。- 你的代码中
Object.values(data)执行后得到的是[data.row1, data.row2],用扩展运算符传入Object.assign后,实际执行的逻辑是Object.assign(data.row1, data.row2):也就是把data.row2的属性直接拷贝到了data.row1这个原始对象上,自然会导致data里的row1属性被修改。此时flat变量拿到的返回值其实就是被修改后的data.row1的引用。
2. Object.freeze不生效的原因
Object.freeze是浅冻结操作:它仅能冻结传入对象本身的属性增删改、以及属性值的引用修改,无法递归冻结对象属性指向的内层对象。- 你只冻结了外层的
data对象,仅能保证data.row1、data.row2的指向不会被修改,但data.row1本身这个内层对象没有被冻结,所以修改它的属性不会被限制。
正确的展平写法
要避免修改原始对象,只需要给Object.assign传入一个空对象作为目标即可:
let flat = Object.assign({}, ...Object.values(data))
此时所有属性都会拷贝到新的空对象上,完全不会触碰原始data里的任何内容。
内容的提问来源于stack exchange,提问作者newandlost
相关产品推荐
相关产品推荐

