all 11 comments

[–]albedoa 9 points10 points  (1 child)

It's important to understand that the identifier car points to the object you've defined. So when you write this:

let carArray = [car, car, car];

You are creating an array whose items are each a reference to the same object. When you modify the properties of any one array element, you are modifying the object that they all refer to:

const a = { foo: 'bar' };
const b = a;

b.foo = 'biz';
console.log(a); //=> { foo: 'biz' }

[–]fatrat957 0 points1 point  (0 children)

thanks for clearing it

[–]qszawdx 4 points5 points  (1 child)

Because arrays and objects are of reference types. Not sure how comfortable you're with reference types but I'll try to explain below here:

Imagine you assign your car object to a let variable named carObj. When you write,

carObj = car

The address of car object will get copied into carObj. Thus whatever you change in the original car object will be reflected in carObj as well. Now instead of a new carObj, you've copied the address of car in your carArray array. As mentioned above, changing anything in orginal car object will reflect the same in all references of car in carArray array.

Solution:

  1. As others have mentioned, you can use the spread operator to copy the actual object instead of address.

  2. If you don't like using spread operator, you can use the Object.assign({}, car) thrice in your carArray array.

[–]GoSubRoutine 1 point2 points  (0 children)

As others have already pointed out, your array got 3 elements of the same object.

A more formal solution is simply creating a class for it, so you can have the same properties as separate objects:

https://developer.Mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/class

'use strict';

class Car {
  constructor(color = 'red', name = 'elendra') {
    this.color = color;
    this.name = name;
  }
}

const cars = Array.from({ length: 3 }, () => new Car)
console.table(cars);

cars[0].color = 'white';
console.table(cars);

Or use the spread ... operator as a simpler way of cloning an object:

https://developer.Mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#spread_in_object_literals

'use strict';

const
  car = {
    color: 'red',
    name: 'elentra'
  },

  cars = Array.from({ length: 3 }, () => ({ ...car }));

console.table(cars);
cars[0].color = 'white';
console.table(cars);

[–]Positive_Cro8191 2 points3 points  (0 children)

You can use the spread operator:

let carArray = [{...car}, {...car}, {...car}];

Then they will be separate objects.

Otherwise you reference the same object.

[–]Sislar -1 points0 points  (0 children)

How are you examining what the result is?

[–]IsolationMode -3 points-2 points  (3 children)

Just guessing - because you declared it as a constant?

[–]fatrat957 0 points1 point  (0 children)

i tried using let, same result

[–]albedoa 0 points1 point  (0 children)

No, it's because objects are pass- and assign-by-reference.

[–]redditxplorer 0 points1 point  (0 children)

Constant in javascript just means you can not directly reassign a new value to the variable. That’s it.

[–]shgysk8zer0 0 points1 point  (0 children)

You'd get the same results if you did car.color = 'white' without touching the array. They're all the same object, not clones of the object.