DEV Community

Cover image for Why are the results like this?
Lawson
Lawson

Posted on

Why are the results like this?

const defaultEmployee = {
  tasks: []
}

const employees = []

const NUMEBR_OF_EMPLOYEE = 5
const INDEX_CEO = 0

for (let index = 0; index <= NUMEBR_OF_EMPLOYEE; index++) {
  const employee = {
    ...defaultEmployee,
    role: index
  }

  if (employee.role === INDEX_CEO) {
    employee.tasks.push({ salary: 10.000 })
  } else {
    employee.tasks.push({ salary: 1.0 })
  }

  employees.push(employee)
  console.log(defaultEmployee)
}

console.log(employees)
Enter fullscreen mode Exit fullscreen mode

Result:

Image-description

Top comments (1)

Collapse
 
gilfewster profile image
Gil Fewster • Edited

When you use the spread operator ...defaultEmployee to copy your original object, it only creates a shallow copy of the original object.

The tasks array on each of your new objects is just a reference to the original array, which means every item you push onto the array will appear on all of your objects.

One way you could approach this is to use a class rather than a plain object:

const NUMBER_OF_EMPLOYEES = 5
const INDEX_CEO = 0
const BASE_SALARY = 1
const CEO_SALARY = 10

class Employee {
  tasks = []
  role = null
  constructor (role) {
    this.role = role
  }

  addTask (task) {
    this.tasks.push(task)
  }

}

const employees = []

for (let index = 0; index < NUMBER_OF_EMPLOYEES; index++) {
  const employee = new Employee(index)
  const salaryTask = {salary: BASE_SALARY}

  if (index === INDEX_CEO) {
    salaryTask.salary = CEO_SALARY
  }
  employee.addTask(salaryTask)

  employees.push(employee)
}

console.log(employees)
Enter fullscreen mode Exit fullscreen mode

If we're going to go down that road, then we might also think about naming the properties a bit differently, since putting salary in a task property feels a bit odd. We an also use a couple of functions to create new employees with specific properties for CEO or Manager roles while we're at it:

const BASE_SALARY = 1
const CEO_SALARY = 10
const MANAGER_SALARY = 5
const TITLES = {
  CEO: 'CEO',
  MANAGER: 'Manager',
  PROGRAMMER: 'Programmer'
}
const NUMBER_OF_PROGRAMMERS = 5


class Employee {
  id = null
  title = TITLES.PROGRAMMER
  salary = BASE_SALARY
  tasks = []

  constructor (id) {
    this.id = id
  }

  addTask (task) {
    this.tasks.push(task)
  }

}


function makeCEO (id) {
  const employee = new Employee(id)
  employee.salary = CEO_SALARY
  employee.title = TITLES.CEO
  employee.addTask("Run the show")
  employee.addTask("Attract investors")
  return employee;
}

function makeManager (id) {
  const employee = new Employee(id)
  employee.salary = MANAGER_SALARY
  employee.title = TITLES.MANAGER
  employee.addTask("Boss around the programmers")
  employee.addTask("Make the CEO look good")
  return employee
}

// initialise the employees array 
// with a ceo and two managers
const employees = [
  makeCEO(0),
  makeManager(1),
  makeManager(2)
]

// use a loop to add our team of 5 programmers
for (let i = 0; i < NUMBER_OF_PROGRAMMERS; i++) {
  const employee = new Employee(employees.length)
  employee.tasks = ['Write software', 'Find bugs', 'Drink Coffee']
  employees.push(employee)
}

console.log(employees)
Enter fullscreen mode Exit fullscreen mode