简体   繁体   English

为什么数组中的原始项目被Object.assign覆盖?

[英]Why is the original item in my array being overwritten with Object.assign?

I have a unit test that is producing something I didn't expect: 我有一个单元测试正在产生我没想到的东西:

Background: I'm making a simple todo list with Angular/test driven development. 背景:我正在使用Angular /测试驱动开发制作一个简单的待办事项清单。

Problem: When I call editTask on an item in the array, it changes the item's value. 问题:当我在数组中的某个项目上调用editTask时,它将更改该项目的值。 But, I don't see how it's changed in the original array because the original array is never accessed in the method I'm testing. 但是,我看不到它在原始数组中的变化,因为从未在我测试的方法中访问原始数组。 Please help me connect HOW the original array is being changed? 请帮助我连接如何更改原始阵列? It seems Object.assign is doing this, but why? 似乎Object.assign正在这样做,但是为什么呢?

 describe('editTask', () => {
    it('should update the task by id', () => {
      const dummyTask1 = { id: 1, name: 'test', status: false };
      service.tasks.push(dummyTask1); //refers to TestBed.get(TaskService)
      const id = 1;
      const values = { name: 'cat', status: false };

      service.editTask(id, values);
      console.log(service.tasks); // why does this log this object? [Object{id: 1, name: 'cat', status: false}]
      expect(service.tasks[0].name).toEqual(values.name); // Test passes
    });
  });

Here is the method I'm testing: 这是我正在测试的方法:

  editTask(id, values) {
    const task = this.getTask(id);

    if (!task) {
      return;
    }

    Object.assign(task, values); //How does this line change the array?

    return task;
  }

  getTask(id: number) {
    return this.tasks.filter(task => task.id === id).pop(); //is this altering the original array somehow?
  }

If needed, here's the full Angular service: 如果需要,这是完整的Angular服务:

export class TaskService {
  tasks: any = [];
  lastId = 0;

  constructor() { }

  addTask(task) {
    if (!task.id) {
      task.id = this.lastId + 1;
    }

    this.tasks.push(task);
  }

  editTask(id, values) {
    const task = this.getTask(id);

    if (!task) {
      return;
    }

    Object.assign(task, values);

    return task;
  }

  deleteTask(id: number) {
    this.tasks = this.tasks.filter(task => task.id !== id);
  }

  toggleStatus(task) {
    const updatedTask = this.editTask(task.id, { status: !task.status});

    return updatedTask;
  }

  getTasks() {
    return of(this.tasks);
  }

  getTask(id: number) {
    return this.tasks.filter(task => task.id === id).pop();
  }
}

Here is the github repo: https://github.com/capozzic1/todo-tdd 这是github仓库: https : //github.com/capozzic1/todo-tdd

The getTask() method is getting a reference to the item in the array using the array filter() method. getTask()方法正在使用数组filter()方法获取对该数组中项目的引用。

It then uses Object.assign() to change the properties of the item. 然后,它使用Object.assign()更改项目的属性。 The Object.assign() method is used to copy the values of all enumerable own properties from one or more source objects to a target object. Object.assign()方法用于将所有可枚举的自身属性的值从一个或多个源对象复制到目标对象。 It will return the target object. 它将返回目标对象。

So now the values of the reference in memory of the item is changed. 因此,现在该项目在内存中的引用值已更改。 Because it is a reference in memory you will see the original item being changed. 因为它是内存中的引用,所以您将看到原始项目被更改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM