修改函数中的对象时出现意外结果

IT技术 javascript reactjs
2021-05-24 15:25:03

当我在一个函数中修改一个对象时,我得到了一个奇怪的结果,有趣的是,当我在浏览器控制台中做同样的事情时,我得到了我期望的结果,但在react中它似乎不起作用
这是代码

const makeChanges = i => {
  i.foo = "test";
  i["new"] = "i am new";

  return i;
};

function App() {
  var A = {
    foo: "foo",
    bar: "bar"
  };

  console.log(A);

  A = makeChanges(A);

  console.log(A);
  //the render code...
}

当前结果:

Object {foo: "test", bar: "bar", new: "i am new"}
Object {foo: "test", bar: "bar", new: "i am new"}

预期结果:

Object {foo: "foo", bar: "bar"}
Object {foo: "test", bar: "bar", new: "i am new"}

这是一个工作示例,请查看控制台以查看结果:

2个回答

问题是你修改了i它指向原始对象A要解决它,只需“克隆” i

例子:

const makeChanges = ({ ...i }) => {
  i.foo = "test";
  i["new"] = "i am new";

  return i;
};

或者

const makeChanges = (i) => {
  const result = { ...i };
  // or
  // const result = Object.assign({}, i);
  result.foo = "test";
  result["new"] = "i am new";

  return result;
};

或者

const makeChanges = (i) => {
  return { ...i, foo: "test", "new": "i am new" } ;
};

工作示例:https : //codesandbox.io/s/blue-wave-mhnpp

查看spread (...)语法:https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax

我认为渲染输出是异步的。并且 console.log 保留它必须打印的对象的引用。
我们也知道如果我们将对象作为函数属性传递,那么它会通过引用传递
所以
在这个代码中,对象 A 有一些地址(比如 abc)它引用。
并且abc处的值是对象 A 的值

当您在函数makeChanges 中传递 A 时,地址abc的值已更改并且控制台必须打印abc处的值,这就是为什么记录与地址abc 处的值相同的值
如果您想看区别然后你可以通过Object.assign制作对象的深拷贝

const makeChanges = i => {
  i.foo = "test";
  i["new"] = "i am new";

  return i;
};

function App() {
  var A = {
    foo: "foo",
    bar: "bar"
  };

  console.log(A);

  A = makeChanges(Object.assign({},A));

  console.log(A);
  //the render code...
}

输出将 b

Object {foo: "foo", bar: "bar"}
Object {foo: "test", bar: "bar", new: "i am new"}

由于Object.assign({},A) U 在不同的内存中创建新对象,因此更改这不会影响内存abc 中的值abc示例)