DEV Community

Julie Cherner
Julie Cherner

Posted on

Prototypes in Javascript in 5 minutes

JavaScript is an object-oriented language and according to Wilkipedia:

Object-oriented programming (OOP) is a programming paradigm based on the concept of "objects", which can contain data and code: data in the form of fields (often known as attributes or properties), and code, in the form of procedures (often known as methods).

So let’s dive into Javascript objects and their prototypes by building a simple object.

A method “message” was added with the anonymous function. “This” in the method is used to connect the variables inside of the method with the object.

const object = {
 user: "guest",
 where: "dev.to",
 message: function () {
   console.log(`${this.user}, welcome to ${this.where}`)
 }
}

console.log(object) // result from the console
// {user: 'guest', where: 'dev.to', message: ƒ}
// message: ƒ ()
// user: "guest"
// where: "dev.to"
// [[Prototype]]: Object

console.log(object.message()) // guest, welcome to dev.to

console.log(object.__proto__)// result from the console

//{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, //hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
//constructor: ƒ Object()
//hasOwnProperty: ƒ hasOwnProperty()
//isPrototypeOf: ƒ isPrototypeOf()
//propertyIsEnumerable: ƒ propertyIsEnumerable()
//toLocaleString: ƒ toLocaleString()
//toString: ƒ toString()
//valueOf: ƒ valueOf()
//__defineGetter__: ƒ __defineGetter__()
//__defineSetter__: ƒ __defineSetter__()
//__lookupGetter__: ƒ __lookupGetter__()
//__lookupSetter__: ƒ __lookupSetter__()
//__proto__: (...)
//get __proto__: ƒ __proto__()
//set __proto__: ƒ __proto__()
Enter fullscreen mode Exit fullscreen mode

Pay attention that in the prototype of the object is a property of one more prototype and inside of this prototype can be one more prototype and so on.

Another way to get the prototype of the object is:

Object.getPrototypeOf(object)
Enter fullscreen mode Exit fullscreen mode

Lets try to extract one of prototype’s method

console.log(object.hasOwnProperty()) // false 
Enter fullscreen mode Exit fullscreen mode

It works!

Let's add the same property to the object and console.log it:

const object = {
 user: "guest",
 where: "dev.to",
 message: function () {
   console.log(`${this.user}, welcome to ${this.where}`)
 },
 hasOwnProperty : function () {
  console.log("the method was added to the object")
 }
}

console.log(object.hasOwnProperty()) // the method was added to the object
Enter fullscreen mode Exit fullscreen mode

So we can make an assumption about what the order of the search in the object is:

  1. First search in the object
  2. After in the prototype of the object
  3. After in the prototype of the prototype…

How to set prototype:

  • With Object.create()
const objectWithProto = Object.create(object)

console.log(objectWithProto)// {} - empty object
console.log(objectWithProto.message()) // guest, welcome to dev.to - message method of prototype

console.log(objectWithProto.__proto__)// results from the console
//{user: 'guest', where: 'dev.to', message: ƒ}
//message: ƒ ()
//user: "guest"
//where: "dev.to"
//[[Prototype]]: Object
Enter fullscreen mode Exit fullscreen mode
  • With constructor

Creating constructor

function User (user, where) {
  this.user = user;
  this.where = where
}
Enter fullscreen mode Exit fullscreen mode

Creating method for the prototype

const userPrototype = {
 message () {
    console.log(`${this.user}, welcome to ${this.where}`)  }
}
Enter fullscreen mode Exit fullscreen mode

Adding the method to the prototype of the object

User.prototype = userPrototype;
Enter fullscreen mode Exit fullscreen mode

Adding User constructor to prototype (that takes parameters from the constructor and that can be passed to message method in the prototype)

User.prototype.constructor = User;

console.log(User) // ƒ User (user, where) {
  this.user = user;
  this.where = where
}

console.log(User.__proto__) // ƒ () { [native code] }
Enter fullscreen mode Exit fullscreen mode

Let’s check what we’ve got:

const myUser = new User('Julie Cherner', dev.to - author);

myUser.message() // Julie Cherner, welcome to dev.to - author

console.log(myUser) // User {user: 'Julie Cherner', where: 'dev.to - author'}

console.log(myUser.__proto__) // results from console
//{message: ƒ, constructor: ƒ}
//constructor: ƒ User(user, where)
//message: ƒ message()
//[[Prototype]]: Object
Enter fullscreen mode Exit fullscreen mode

So, prototypes provide great opportunities for the inheritance of properties for objects in Javascript.

Discussion (0)