Prototypes in Javascript in 5 minutes
Tags: javascript, object, prototype, oop
Published: 2022-05-06 10:27:52

JavaScript is an object-oriented language and [according to Wilkipedia](https://en.wikipedia.org/wiki/Object-oriented_programming):

> 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.

```js
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__()
```
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 (and preferable) way to get the prototype of the object is:
``` js
Object.getPrototypeOf(object)
```
Lets try to extract one of prototype’s method
```js
console.log(object.hasOwnProperty()) // false 
```
It works!

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

```js
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
```
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()**

```js
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
```
- **With constructor**

**Creating constructor**

```js
function User (user, where) {
  this.user = user;
  this.where = where
}
```
Creating method for the prototype

```js
const userPrototype = {
 message () {
    console.log(`${this.user}, welcome to ${this.where}`)  }
}
```
Adding the method to the prototype of the object

```js
User.prototype = userPrototype;
```

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

```js
User.prototype.constructor = User;

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

console.log(User.__proto__) // ƒ () { [native code] }
```

**Let’s check what we’ve got:**

```js
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
```

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