Object.create method JavaScript

In JavaScript, Prototype inheritance is much easier than you would have imagined. Simply understand the fundamentals, like we always do!

Inheritance in JavaScript is prototype-based. Every constructor has a property called prototype. For more information about the basics of prototypes, click here.

Master constructor object ‘Object’

Object is the master constructor in JavaScript. Don’t forget to take a note of the capitalization of letter ‘O’ in Object. It’s a
function constructor. Directly or indirectly, every object is created by using Object (master object). Since, it is available in the global space, you can access it directly. If you console.dir(Object), you can view all methods that are available to Object. One of the methods is create(). It enables prototypal inheritance in JavaScript.

console.dir(Object);

Object.create Method

Syntax

Object.create(prototypeObject, propertiesObject);

The Object.create method takes two arguments. First argument must be either an object or null. The second argument is optional and used to set properties. These properties are set in object’s prototype.

Creating Objects

const myObject = Object.create(Object.prototype);
console.dir(myObject);

In the above example, the myObject object is created by using Object’s prototype. This means myObject’s creator is Object.prototype. If you inspect myObject, you can view the following:
Inspecting Object
myObject does not contain anything. However, its __proto__ property is a reference to the Object’s prototype. Hence, you can call methods on myObject that are available in Object’s prototype. If you create an object literal by using const myLiteral = {};, it possesses the same __proto__ because internally every object’s __proto__ is set to Object.prototype.To create an object without setting its __proto__ reference to Object.prototype, pass null as an argument. To verify this, inspect the object. As shown in the image below, it does not contain __proto__ property.

const myObject = Object.create(null);
console.dir(myObject);

Object.create(null)

The Object.create() method also creates objects from constructors. It is similar to using the new keyword. The only difference is that by using the new keyword, you can run the constructor. Hence, it will set the initial properties in the constructor. Whereas, the Object.create() method doesn’t run the constructor and hence the initial properties are not set.

const Car = function(color) {
  this.color = color;
};

let car1 = new Car('red');
let car2 = Object.create(Car.prototype);

console.dir(car1);
console.dir(car2);

New vs Object.create

Extending a Constructor

The main use of the Object.create() method is to extend the constructor. This means that you can inherit methods from a constructor’s prototype properties to other constructors. To extend a constructor, set a prototype reference of one object to another by using the Object.create() method.
Note: Only the constructor’s prototype is inherited and not the constructor.

const Car = function(color) {
  this.color = color;
};

Car.prototype.getColor = function() {
  return this.color;
}

const ToyCar = function() {};

ToyCar.prototype = Object.create(Car.prototype);

const legoCar = new ToyCar();

console.log(legoCar);

Object.create



Verifying Prototype

In the above example, ToyCar’s __proto__ is set to Car and Car’s __proto__ is set to Object. The isPrototypeOf method verifies if legoCar, which is originally created by using the ToyCar constructor, is a prototype of ToyCar, Car and Object. The instanceof operator also performs the similar task.

const Car = function() {};
const ToyCar = function() {};

ToyCar.prototype = Object.create(Car.prototype);

const legoCar = new ToyCar();

// Using the isPrototypeOf method
console.log(ToyCar.prototype.isPrototypeOf(legoCar)); //true
console.log(Car.prototype.isPrototypeOf(legoCar)); //true
console.log(Object.prototype.isPrototypeOf(legoCar)); //true

// Using the instanceof operator
console.log(legoCar instanceof ToyCar); //true
console.log(legoCar instanceof Car); //true
console.log(legoCar instanceof Object); //true

Conclusion

In the classical inheritance, you can create a subClass from a superClass. The subClass inherits all methods of the superClass. In JavaScript, a subConstructor inherits all methods from a superConstructor by using the Object.create method. Contrary to the classical inheritance, where methods of superClass are copied to subClass, JavaScript uses a prototype reference to access methods from the superConstructor.

JavaScript Function Constructors

It is very important to understand how JavaScript function constructors work before we move to higher level topics of Object Oriented JavaScript. In this article, I am not going to explain about the JavaScript class constructor. Instead, I’ll explain about ‘function’ constructors.
The ultimate objective of Object Orient Programming is to create objects with ease. Languages like Java have classes and each class can have a constructor, and its job is to set initial properties of the object. In JavaScript, you can create an object by directly using constructors. JavaScript lets you use a function as a constructor, if called in a specific way. And, that’s what this entire article is all about!

Usually, the job of a function is to run a specific job. Let’s say, I want to add two numbers. will write a function that takes two arguments and return the addition of the two numbers.

Sample of a function for adding two numbers:

let add = function(number1, number2) {
 return number1 + number2;
};

let sum = add(1, 2);

Now, let’s look at an example of a function constructor.

let Car = function(color) {
 this.color = color;
};

let redCar = new Car('red');

As shown in the above example, a regular function takes arguments. It performs an action within the body of the function and returns the result. A regular function may or may not return anything.
Function constructor, on the other hand, accepts color as an argument and sets it to its this.The constructor function does not contain a return statement. Instead, it returns a new object with the property that is passed as an argument.

The basic syntax difference for executing a regular function and a constructor function is the usage of the new keyword.

If you were to manually create an object without using the constructor function, the syntax will look like following:

let redCar = {
 color: 'red'
};

If you inspect the newly created object in a browser, this is how it would look like:


JavaScript function constructor inspect

As you can notice, it has a color property which is set to ‘red’; The property, __proto__, is its creator. If you expand the __proto__, you will see the following:

JavaScript function constructor inspect

The reference to the constructor that set the initial property is the Car constructor that you used to create redCar.

Drawbacks of not using new

Now, let’s consider a scenario where you execute a constructor function as a regular function without using the keyword ‘new’.

let Car = function(color) {
  this.color = color;
};

let redCar = Car('red');

In this case, this.color = color will create a new property color in the global space. You can verify the result by using console.log(window.color);

To prevent such error, add se use strict, which throws the following exception:

error calling function constructor without 'new' keyword

You can also use the new.target to throw a customized error message..

let Car = function(color) {
  if (!new.target) throw 'Car() must be called with new';
  this.color = color;
};

let redCar = new Car('red');

Private Vs Public properties

In JavaScript, all object properties are public, which means you can access it directly. For example, redCar.color. JavaScript does not have a native support for private property. Private properties are the properties you cannot access directly by using a dot notation. However, you can call a getter or have a getter method like getColor to access it and use closure.

let Car = function(_color) {
  this.setColor = function(color){
    _color = color;
  }
  this.getColor = function() {
    return _color;
  };
};

let redCar = new Car('red');

console.log(redColor.getColor());

Here _color is a private variable that cannot be accessed by the object using redCar._color.
Since it is a closure, the methods have access to them.

Adding methods to a Constructor

Best way to have methods is to set methods in prototype space. For more information about settings methods in the prototype space, go to Prototype.