首页 > 解决方案 > Object.assign(...as) 更改输入参数

问题描述

Object.assign(...as)似乎改变了输入参数。例子:

const as = [{a:1}, {b:2}, {c:3}];
const aObj = Object.assign(...as);

我将一个对象字面量数组解构为 assign 函数的参数。我省略了console.log陈述。这是节点 13.7 的标准输出:

如前分配: [ { a: 1 }, { b: 2 }, { c: 3 } ]

aObj: { a: 1, b: 2, c: 3 }

分配后: [ { a: 1, b: 2, c: 3 }, { b: 2 }, { c: 3 } ]

读者可能会注意到as第一个元素已整体更改。将新数组bs元素更改为不可变对象(使用freeze

const bs = [{a:1}, {b:2}, {c:3}];
[0, 1, 2].map(k => Object.freeze(bs[k]));
const bObj = Object.assign(...bs);

导致错误:

TypeError:无法添加属性 b,对象在 Function.assign (<anonymous>) 处不可扩展

这表明该论点确实正在改变。

真正让我感到困惑的是,即使绑定我的数组,,cs也可以通过将它currying到一个函数(我认为你在JS中称之为闭包)

const cs = [{a:1}, {b:2}, {c:3}];
const f = (xs) => Object.assign(...xs);
const g = () => f(cs);                            

const cObj = g();

返回:

赋值前的 cs: [ { a: 1 }, { b: 2 }, { c: 3 } ] cObj: { a: 1, b: 2, c: 3 } 赋值后的 cs: [ { a: 1, b: 2, c: 3 }, { b: 2 }, { c: 3 } ]

这里出了什么问题?以及如何Object.assign在不破坏其第一个论点的情况下安全地使用?

标签: javascript

解决方案


Object.assign不是纯函数,它会覆盖它的第一个参数target

这是它在MDN上的条目:

Object.assign(目标,...来源)

参数

目标

目标对象 - 将源的属性应用到什么,修改后返回。

来源

源对象 — 包含您要应用的属性的对象。

返回值

目标对象。

关键短语是“[目标]被修改后返回”。为避免这种情况,请将空对象文字{}作为第一个参数传递:

const aObj = Object.assign({}, ...as);

推荐阅读