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

时间:2018-09-06 02:31:18

标签: arrays angular tdd

我的单元测试所产生的结果出乎我的意料:

背景:我正在使用Angular /测试驱动开发制作一个简单的待办事项清单。

问题:当我在数组中的某个项目上调用editTask时,它将更改该项目的值。但是,我看不到它在原始数组中的变化,因为从未在我测试的方法中访问原始数组。请帮助我连接如何更改原始阵列?似乎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
    });
  });

这是我正在测试的方法:

  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?
  }

如果需要,这是完整的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();
  }
}

这是github仓库:https://github.com/capozzic1/todo-tdd

1 个答案:

答案 0 :(得分:1)

getTask()方法正在使用数组filter()方法获取对数组中项目的引用。

然后它使用Object.assign()来更改项目的属性。 Object.assign()方法用于将所有可枚举的自身属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。

因此,现在更改了该项目在内存中的引用值。因为它是内存中的引用,所以您将看到原始项目被更改。