Javascript spread & inheritance

Viewed 535

I am fairly new to javascript development and still learning concepts. I have a question regarding the spread "operator" (...). Can it be used as an inheritance-like mechanism or does it have side effects that should make me avoid this ?

Example

const A = {
  prop1: "value1",
  prop2: function() {return this.prop1}
}

const B = {
  ...A,
  prop1: "updated_value1",
  prop3: "value3"
}

B here can be seen has being inherited from A, A.prop2() returns value1, and B.prop2() returns updated_value1 has one would expect from any inherited object.

Is this valid ?

6 Answers

The code you posted is working as expected, as properties from A are copied to B. However, this is not an example of inheritance, it's just a shallow copy.

In your example all properties are primitives, consider what happens if we add a reference to A:

const A = {
  prop1: "value1",
  prop2: function() {return this.prop1},
  obj: { value: 1 }
}

const B = {
  ...A,
  prop1: "updated_value1",
  prop3: "value3"
}

Now, changing A.obj.value will also modify B.obj.value which will essentially make all B's to share their obj with A and among themselves. This could be useful in some situations, but it's not exactly inheritance.

For inheritance it's best to use "Javascript classes"

You can't really call it inherence. It's a merge. By writing this

const B = {
  ...A,
  prop1: "updated_value1",
  prop3: "value3"
}

props1 from A will be overwritten by prop1 from B. So yes, B.prop2() will return updated_value1 and it's completely fair.

In your case I would tend to use Object Assign since less things can go wrong:

const A = {
  prop1: "value1",
  prop2: function() {return this.prop1}
}

cont B = Object.assign(A, {
  prop1: "updated_value1",
  prop3: "value3"
});

But still this is no real inheritance.

It might look like inheritance but in fact all you are defining there is :

const A = {
  prop1: "value1",
  prop2: function() {return this.prop1}
}

const B = {
  prop1: "value1",
  prop2: function() {return this.prop1},
  prop1: "updated_value1",
  prop3: "value3"
}

In essence you are overriding the member defined 2 lines up for object B. It is not inheritance because the definition of the members will be owned by object B instead of a prototype of B for example. When referring to B.prop1 the engine will not have to look on prototypes for the property, which is what inheritance would do if you were using protos

I will not call this inheritance.Using the spread operator with object is similar to use Object.assign().This method what it does is to copy the values of all enumerable own properties from one or more source objects to a target object. See documentation

{...A} simply creates a copy of all the key-values from 'A' and sets it to 'B'. Then you update the property prop1 of 'B' to updated_value1. 'A' remains unchanged. This is completely valid

Related