Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/404.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript JS不可变对象保持相同的对象类型_Javascript_Redux_Immutability - Fatal编程技术网

Javascript JS不可变对象保持相同的对象类型

Javascript JS不可变对象保持相同的对象类型,javascript,redux,immutability,Javascript,Redux,Immutability,假设我有一节课 class Test { constructor() { this.name = 'name'; this.arr = []; } } 我需要从这个类中创建多个实例 const entities = { 1: new Test(), 2: new Test() } 现在,我需要以浅克隆的方式更新其中一个属性 const newEntities = { ...entities, [1]: {

假设我有一节课

class Test {

  constructor() {
        this.name = 'name';
        this.arr = [];
    }
}
我需要从这个类中创建多个实例

const entities = {
   1: new Test(),
   2: new Test()
} 
现在,我需要以浅克隆的方式更新其中一个属性

const newEntities = {
    ...entities,
    [1]: {
      ...entities[1],
      name: 'changed'
  }
}

console.log(newEntities[1].arr === entities[1].arr) <=== true
const newEntities={
…实体,
[1]: {
…实体[1],
名称:“已更改”
}
}
console.log(newEntities[1]。arr===entities[1]。arr)您可以在
[1]
对象上使用

因此,它将是:

Object.setPrototypeOf(newEntities[1], Test.prototype);

您不能使用对象分解来保留实例,因此需要实现此行为

第一个示例,在构造函数中设置新属性:

class Test {
  constructor(props) {
    props = props == null ? {} : props;

    this.name = 'name';
    this.arr = [];

    Object.assign(this, props);
  }
} 

const newEntities = {
  ...entities,
  [1]: new Test({ ...entities[1], name: 'changed' })
}
class Test  {
  constructor() {
    this.name = 'name';
    this.arr = [];
  }

  assign(props) {
    props = props == null ? {} : props;
    const instance = new Test();

    Object.assign(instance, this, props);

    return instance;
  }
} 

const newEntities = {
  ...entities,
  [1]: entities[1].assign({ name: 'changed' })
}
Sencod示例,使用自定义方法:

class Test {
  constructor(props) {
    props = props == null ? {} : props;

    this.name = 'name';
    this.arr = [];

    Object.assign(this, props);
  }
} 

const newEntities = {
  ...entities,
  [1]: new Test({ ...entities[1], name: 'changed' })
}
class Test  {
  constructor() {
    this.name = 'name';
    this.arr = [];
  }

  assign(props) {
    props = props == null ? {} : props;
    const instance = new Test();

    Object.assign(instance, this, props);

    return instance;
  }
} 

const newEntities = {
  ...entities,
  [1]: entities[1].assign({ name: 'changed' })
}

来自MDN:根据现代JavaScript引擎优化属性访问的性质,更改对象的[[Prototype]]在每个浏览器和JavaScript引擎中都是一个非常缓慢的操作。否则,您可以从Test
const newObj=object.create(Test.Prototype)
的Prototype创建一个新对象,并将其与
[1]合并
object,但我不确定哪种方式更快。我更喜欢用这个,因为它更清晰。(如果没有任何严格的性能要求或限制)
实体的属性名称和值并非如问题标题所示是不变的。这是否会影响您需要执行的操作?在第二个示例中-newEntities[1]===entities[1]?true或false此选项为false,因为该方法正在返回新实例您正在创建新实例,但未保留其余属性。例如,arr.I刚刚注意到,我做了一个小的更改,看起来更好,在您的第一个方法中,您没有更改name属性。