Categories
Object-Oriented JavaScript

Object-Oriented JavaScript — Inheritance and Copying Objects

Spread the love

JavaScript is partly an object-oriented language.

To learn JavaScript, we got to learn the object-oriented parts of JavaScript.

In this article, we’ll look at copying objects.

Deep Copy

We can deep copy an object by copying an object’s properties recursively from the source object to the target object.

For instance, we can write:

function deepCopy(source, target = {}) {
  for (const key in source) {
    if (source.hasOwnProperty(key)) {
      if (typeof source[key] === 'object') {
        target[key] = Array.isArray(source[key]) ? [] : {};
        deepCopy(source[key], target[key]);
      } else {
        target[key] = source[key];
      }
    }
  }
  return target;
}

We loop through each key of the source .

Then we check each property if it’s an own property.

Then we check if the source[key] object is an object.

If source[key] is an array, then we create an array, then we do the copying.

If it’s an object, then we call deepCopy recursively to make the copy.

Otherwise, we assign the value from the source to the target .

Once that’s all done, we return the target .

Then we can use it by writing:

const foo = {
  a: 1,
  b: {
    c: 2
  }
}
const bar = deepCopy(foo, {});

console.log(bar);

deepCopy will copy all the own properties from foo to bar recursively.

So bar is:

{
  "a": 1,
  "b": {
    "c": 2
  }
}

Array.isArray lets us check if something is an array regardless of context.

Using object() Method

We can create an object function to create a function that returns an instance of a constructor.

This suggestion is from Douglas Crockford and it makes setting the prototype easy since it takes the prototype object.

For instance, we can write:

function object(proto) {
  function F() {}
  F.prototype = proto;
  return new F();
}

We create the object function with the proto property.

Then we set that as the F ‘s prototype .

And we return an instance of F .

This is different from Object.create since we have an instance of the constructor.

We can then use it by writing:

const obj = object({
  foo: 1
});

Then obj would inherit from the object we passed in.

Mix Prototypal Inheritance and Copying Properties

We can mix prototypical inheritance with copying properties.

To do that, we can expand the object function by writing:

function object(proto, moreProps) {
  function F() {}
  F.prototype = proto;
  const f = new F();
  return {
    f,
    ...moreProps
  };
}

const obj = object({
  foo: 1
}, {
  bar: 2
});

We add a moreProps parameter to the object function, which lets us add more properties by passing in the 2nd argument to it.

moreProps is spread into the object we return so that we return the new object.

Therefore, obj is {f: F, bar: 2} since we inherit from F.prototype and moreProps .

Conclusion

We can mix prototypical inheritance with copying properties to get all the properties we want in an object.

A deep copy can be done by recursively copying properties from the source object to the target.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *