Categories
TypeScript

JavaScript Object Features in TypeScript — Inheritance

Spread the love

TypeScript is a natural extension of JavaScript that’s used in many projects in place of JavaScript.

However, not everyone knows how it actually works.

In this article, we’ll look at some features of JavaScript that should be used in TypeScript projects, including object inheritance.

JavaScript Object Inheritance

JavaScript objects can have a link to another object.

The object is called the prototype.

Objects inherit properties and methods from the prototype.

This allows us to implement complex features to be defined once and used consistently.

When we create an object using the literal syntax, then its prototype is Object .

Object provides some basic features they inherit like the toString method that returns the string representation of an object.

For instance, if we have the following object:

const obj = {
  foo: 1,
  bar: "baz"
};

console.log(obj.toString());

If we define obj and run:

console.log(obj.toString());

We get [object Object] logged.

That’s what the default toString method does in the Object ‘s prototype.

Object’s Prototype

Object is the prototype for most objects.

We can also use some methods directly.

There’s the getPrototypeOf , setPrototypeOf , and getOwnPropertyNames methods.

getPrototypeOf returns the prototype of an object.

For instance, we can write:

const proto = {};
const obj = Object.create(proto);

let objPrototype = Object.getPrototypeOf(obj);

Then we get that objPrototype is Object .

proto is the prototype of obj since we passed it into Object.create .

Creating Custom Prototypes

Also, we can use the setPrototypeOf method to set the prototype of an existing object.

For instance, we can write:

const proto = {};
const obj = {
  foo: 1
};

Object.setPrototypeOf(obj, proto);
const objProto = Object.getPrototypeOf(obj);
console.log(proto === objProto);

The code above has 2 objects, obj and proto .

Then we call setPrototype with obj and proto to set proto as the prototype of obj .

In the last line, we check is proto refers to the same object as the prototype object returned from getPrototypeOf .

Console log returns true so we know that the prototype of obj is actually proto .

Constructor Functions

A constructor function is used to create a new object, configure its properties, and assign its prototype.

For instance, we can create one by writing:

let Dog = function(name, breed) {
  this.name = name;
  this.breed = breed;
};

Dog.prototype.toString = function() {
  return `name: ${this.name}, breed: ${this.breed}`;
};

We have a Dog constructor function with the name and breed fields.

Then we created an instance method called toString to return the string representation of a Dog instance.

Then we can create a Dog instance and call toString as follows:

console.log(new Dog('joe', 'labrador').toString());

And we get:

'name: joe, breed: labrador'

in the console log output.

We invoked our constructor function with the new keyword.

The arguments are passed in and set as properties of this in the constructor function.

The constructor function configures the object own properties using this , which is set to a new object.

The prototype of the object returned by the constructor has its __proto__ set to Dog.prototype .

So toString is from the Dog instance’s prototype property.

Chaining Constructor Functions

We can chain the constrictor functions of more than one function by writing:

const Animal = function(name) {
  this.name = name;
};

Animal.prototype.toString = function() {
  return `toString: name: ${this.name}`;
};

const Dog = function(name, breed) {
  Animal.call(this, name);
  this.breed = breed;
};

Object.setPrototypeOf(Dog.prototype, Animal.prototype);
Dog.prototype.bark = function() {
  return "woof";
};

const dog = new Dog("joe", "labrador");
console.log(dog.toString());
console.log(dog.bark());

We have a parent Animal constructor which has a toString method in its prototype.

Then we added a Dog constructor, which inherits from the Animal constructor.

In the Dog constructor, we call the call method on Animal to call the parent Animal constructor but with this set to the Dog constructor.

Dog inherits from Animal by calling setPrototypeOf with the child constructor in the first argument and the parent as the 2nd.

Then we add another method to the prototype called bark to Dog ‘s prototype, so we can only be called that on a Dog instance.

toString is available to both Dog and Animal .

Conclusion

JavaScript’s inheritance system isn’t like the other object-oriented language’s inheritance system.

JavaScript has constructor functions and prototypes rather than classes.

Objects can inherit from other objects directly. Constructors can inherit from other constructors.

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 *