使用沉浸器的JavaScript中的DeepCopy对象 [英] DeepCopy Object in JavaScript using immer

查看:114
本文介绍了使用沉浸器的JavaScript中的DeepCopy对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 immer 来转换react/redux状态.我还可以使用沉浸法仅复制对象而不进行转换吗?

I am using immer to transform react/redux state. Can I also use immer to just deep copy an object without transforming it?

import produce, {nothing} from "immer"



const state = {
    hello: "world"
}

produce(state, draft => {})
produce(state, draft => undefined)
// Both return the original state: { hello: "world"}

这是来自官方沉浸式自述文件.这是否意味着将空函数传递给produce会返回原始状态或实际原始状态的深层副本?

This is from the official immer README. Does this mean that passing an empty function to produce returns a deep copy of the original state or actually the original state?

非常感谢您的帮助:)!

Thank you very much for your help :)!

推荐答案

使用

import { produce } from 'immer'

const state = {
  hello: 'world',
}

const nextState = produce(state, draft => {})

nextState.hello = 'new world'
console.log(state, nextState)

输出

Object { hello: "new world" }

Object { hello: "new world" }

这意味着它不会创建对象的深层副本.

which means that it does NOT create a deep copy of an object.

更新:

所以我很感兴趣,并对该库进行了很多测试,这是我的发现.

So I got interested and tested out the library a lot and here are my findings.

我上面编写的代码段只是库中的优化,如果不进行任何更改,它将返回旧状态.但是,如果进行了一些更改,则库将按预期开始运行,并且以后将无法进行突变.也就是说,

The code snippet I wrote above is simply an optimisation in the library which returns the old state if no changes are made. However, if you make some changes, then the library starts functioning as intended and the mutation later is made impossible. That is,

const state = {
  hello: 'world',
}

const nextState = produce(state, draft => {
  draft.hello = 'new world';
})

nextState.hello = 'newer world';

console.log(state, nextState)

将导致错误:TypeError: "world" is read-only

这意味着您的newState是不可变的,您将无法对其进行更改.

Which means that your newState is immutable and you can no longer perform mutations on it.

我发现的另一件相当有趣的事情是,使用class实例时,沉浸失败.也就是说,

Another rather interesting thing I found is that immer fails when using class instances. That is,

class Cls {
  prop = 10;
}

const instance = new Cls();

const obj = {
  r: instance,
};

const newObj = produce(obj, draft => {
  draft.r.prop = 15;
});

console.log(obj, newObj);

结果

r: Object { prop: 15 }

r: Object { prop: 15 }


因此,回到最初的问题,是否可以通过不更改草稿中的任何内容来获得初始Object的深层副本.不,您不能,即使这样做(通过更改仅为愚弄而创建的属性),生成的克隆对象也将是不可变的,并没有真正的帮助.


So to get back to the initial question, can you get a deep copy of the initial Object by changing nothing in the draft. No you cannot, and even if you did (by changing a property created just to fool immer perhaps), the resultant cloned object will be immutable and not really helpful.

这篇关于使用沉浸器的JavaScript中的DeepCopy对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆