DEV Community

loading...
Cover image for Looking at the Prototype

Looking at the Prototype

Cameron Young
Software stormtrooper, Coffee sipper, Father of two. Software blogger of many topics but mainly C# and .net follow me on twitter @sigfualt
・3 min read

Why I care about the prototype

To work with a lot of the cool flashy js frameworks, I was told to understand JavaScript first. Other than the scope of “this” one other concept would confuse me. The idea of prototypes would pop up, and people would always say “Don't worry about that. It is important but not really”. So for the longest, I just ignored the prototype. I could get what I needed and not really have to worry about it. After taking a real dive into es6 and understanding classes and inheritance.

The breakdown

I was noticing that JavaScript was playing by different rules than C# or Java. Side note: I do Java sometimes when needed but not as I used to back in college. Back in my day, Java was the golden child, and we implemented in it. The C++ religion was dying down, and this took its place. It is interesting to see the same pattern happen with python. My professor Dr. Hang Chen (a very sharp man who took little bs. Then there was me, and I had a ton to give) at the time had the view that using Java was making us softer coders and real coders used C++ or C. It is just funny to see this same idea come up in a new era with js and python versus other compiled languages. Okay back to prototypes. I was attacking this with the mindset of a Java/C# coder.

The What

Image of a model prototype chain

Prototypical languages are just different. Now that I have a better understanding of them, I think they are kind of cool. So step one was understanding classical then prototypal inheritance. It took a second to understand that inheritance is different in this language and how simple it is. In JavaScript, all objects including functions have a prototype property. In the diagram above. The property is just a reference to another object we called proto. It would be an object that could stand on its own and could be independent if needed. So when you are calling prop 2 it is not on the object but it is actually on the object’s prototype. That prototype object can also point to another object. Each object can have its prototype. Let's use some code to see an example of the prototype chain. The prototype chain deals with where we have access to a property or method amid a sequence of objects. Those connected by this prototype property, here we are calling proto. The JavaScript engine will do the work for us by searching the prototype chain. We do not have to be explicit with our calls (Ex: we can just say object.prop2 and not object.proto.prop2) Let's see an example of this.

The Code

Here we created two objects with default values and a default function. The second object will have two properties with no function.

// Let's create a car object with some Default values
var car = {
make: 'Default',
model: 'Default',
getCarInfo: function() {
return this.make + ' ' + this.model; 
}
}

var Volvo = {
make: 'Volvo',
model: 'S80'
}
Enter fullscreen mode Exit fullscreen mode

Don't do this in real life. Learn about the proto here. We read docs around here. Now Volvo inherits from car. So when calling a method that doesn't exist on Volvo it will go to Car to find it

Volvo.__proto__ = car;

// Now we can use the getCarInfo()
console.log(Volvo.getCarInfo());
Enter fullscreen mode Exit fullscreen mode

We get the value of "Volvo" because of the prototype chain. It first looks on the Volvo object for that property, finds it then stops. JavaScript engine starts at the top of the chain, works its way down till it finds the needed value.

console.log(Volvo.make);
Enter fullscreen mode Exit fullscreen mode

This will return "Honda Default" as the object has a value for make but not for model. So the prototype is car and finds the model value of Default

var Honda = {
    make: 'Honda'   
}

Honda.__proto__ = car;


console.log(Honda.getCarInfo());
Enter fullscreen mode Exit fullscreen mode

Here we will crate a new function on the car object to hammer home the idea.

car.getCarFullInfo = function() {
    return this.model + ', ' + this.make;   
}

console.log(Volvo.getCarFullInfo());
console.log(Honda.getCarFullInfo());
Enter fullscreen mode Exit fullscreen mode

The value you would get here would be "S80, Volvo" and "Default, Honda" because of how prototypes work. Get the full code here.

The original post can be found Here.

Discussion (6)

Collapse
codingsafari profile image
Nico Braun • Edited

This code is so 90s. I came here reading the title, knowing I am going to be looking ar var and this.

Nowadays, we don't write code like this anymore. Even though its been some years since, you should really look into how es6 changed the game forever.

  • we don't use var, we use let or const instead
  • we really don't use prototypes ever.
  • Volvo should be volvo by convention. We capitalize only stuff that has a constructor which can be invoked with the new keyword.

I personally think JS nowadays is more used with the functional paradigm. I know as a c# person, FP isn't really something you are doing daily. Still, the below is more like how we write that code today.

const cars = [
  {
    make: "Volvo",
    model: "S80"
  },
  {
    make: "Honda"
  }
];

const getCarInfo = ({  make = "1970", model = "Default" }) => `${model}, ${make}`;

cars.forEach((car) => console.log(getCarInfo(car)));
Enter fullscreen mode Exit fullscreen mode

BTW, If you wanted to force typing, well you guessed it, you would use typescript and not prototypes.

Collapse
sigfualt profile image
Cameron Young Author

I wanted to go beneath the syntactic sugar and understand how inheritance and the prototype chain worked. Mozilla has an example in their documentation that’s similar but to me harder to read to me. We don’t code like this daily true. I think it is still good to know what’s going on under the hood in case you have to roll up your sleeves.

Doc link:
(developer.mozilla.org/en-US/docs/W...)

Collapse
patarapolw profile image
Pacharapol Withayasakpunt

What's the difference between .__proto__ and .prototype?

Collapse
peerreynders profile image
peerreynders • Edited

prototype is the property you set on a constructor function - any objects created via new will have that object as their prototype.

// Constructor function
function Car(make, model) {
  if (typeof make === 'string') this.make = make;
  if (typeof model === 'string') this.model = model;
}

function getCarInfo() {
  return `${this.make} ${this.model}`;
}

Car.prototype = {
  make: 'Default',
  model: 'Default',
  getCarInfo,
};

const volvo = new Car('Volvo', 'S80');

console.assert(volvo.getCarInfo() === 'Volvo S80');
Enter fullscreen mode Exit fullscreen mode

While the actual object prototype link is an internal property, i.e. it's implementation dependent to allow for optimization, Firefox's JavaScript engine SpiderMonkey exposed it with __proto__ which was soon copied by other browsers.

ES2015:
1.) deprecates __proto__
2.) turned __proto__ into a getter/setter.

__proto__ in ECMAScript 6

Now if you want to get the prototype of an object use Object.getPrototypeOf() and you can create an object with a prototype with Object.create()

function getCarInfo() {
  return `${this.make} ${this.model}`;
}

const car = {
  make: 'Default',
  model: 'Default',
  getCarInfo,
};

const volvo = Object.create(car);
volvo.make = 'Volvo';
volvo.model = 'S80';

console.assert(volvo.getCarInfo() === 'Volvo S80');
Enter fullscreen mode Exit fullscreen mode

JavaScript's prototypal inheritance is based on Self.

Collapse
sigfualt profile image
Cameron Young Author

Like everything it is deeper than that, I had a cooler response typed up but someone else said it better

"So proto is the actual object that is saved and used as the prototype while Myconstructure.prototype is just a blueprint for proto which, is infact the actual object saved and used as the protoype. Hence myobject.prototype wouldnt be a property of the actual object because its just a temporary thing used by the constructor function to outline what myobject.proto should look like."

(stackoverflow.com/questions/995972...)

Collapse
sigfualt profile image
Cameron Young Author

You don't want to use ".proto" in the real world.
(developer.mozilla.org/en-US/docs/W...)

It was easy to use to make this to prove a point.

Forem Open with the Forem app