What is a prototype in Javascript? And what is an object?
Topics

Wenn du Interesse an einer eigenen Webseite hast, dann ist für dich vielleicht diese Seite interessant. Ich bin dabei, Grundlagen von Webtechnologien zusammenzutragen und zu erklären. Die Möglichkeit, im Internet zu publizieren, sollte jeder nutzen können, der es möchte.


What is an object in Javascript?

Let's start with the console. The console is the most important tool for a beginning programmer. This is where you can debug your code or understand the changing content of your variables by printing them. Open it via the menu of your browser. Don't hesitate, try it now!

how to open the console in firefox how to open the console in opera

To the left you can see the menu of firefox, to the right the menu of opera. You find it there under "Web-Entwickler" or just "Entwickler". In English that would be under "developer" or "developer tools" or "web developer". I have printed some text to the console. Can you find out what it is without looking into the source code?

There are quite a few ways to create objects in Javascript. The first one is this:

<script>
var alive = {}
</script>

In the browser's console you can then visualize a primitive object with properties, even though no properties have been assigned to it, the "archetypal" object one could say. It is a primitive native object in its purest form. Use "console.dir()" to show the properties of any object:

the object with object as prototype

As you can see, its heritage (proto or __proto__) is "object". Even though we have added no additional data to the object, it already has some properties. These are inherited properties. The moment an object is created in javascript it inherits from an ancestor object. The property __proto__ is what is given from "father to son", the actual heritage of the ancestor. This prototype is also an object. It is exactly what the name implies, a "demonstration model for a new technology or future product". In the context of Javascript it is the model for the new object. The prototypal __proto__ property points to this model which is contained in the ancestor. In this sense it "is" the model.

the object in its purest form

Let's create a new object and add properties to this object. We'll call it person:

<script>

var person = {}
        
    person.name = "Johann Schmidt";
    person.address = "Königstr. 9";
    person.lives_in_city = "Bonn";
    person.lives_in_country = "Germany";
 
</script>

Enter this into the console to inspect our object: console.dir (person). Do it now. Play with the arrows and the menu, open up the different properties and get aquainted with this object. It is a primitive object, but in this fashion good for learning purposes.

When you have entered this into the console you can inspect the object. You can see very clearly that our object consists of the properties we added and the prototypal object __proto__ (heritage). I think that it is good to call it that way and not "prototype" because a prototype is again something different.

a new object with some properties

Let's play with these objects. It's fun. Let's say we have a human being who is shot into space and lands on Gliese01228888999. Let's also say he's not alone. So he will colonize Gliese01228888999. This is something we humans are really good at. Johann will forget that he is human. To all the creatures of Gliese01228888999 he is now an alien, he has become John Smith:

<script>
var human = {}
        
    human.name = "Johann Schmidt";
    human.address = "Königstr. 9";
    human.lives_in_city = "Bonn";
    human.lives_in_country = "Germany";
    human.eats = "beefsteak";
    
var alien = {};
        
    alien.name = "John Smith";
    alien.address = "Sunrise boulevard";
    alien.lives_in_city = "Sun city";
    alien.lives_in_country = "Trisol";
    alien.lives_on_planet = "Gliese01228888999";
    
alien.__proto__= human;

console.log("My name is "+human.name+".");
console.log("I don't know why, but my wife calls me "+alien.name+" as of late.");
console.log("We call this place "+alien.lives_in_city+".");
console.log("It's utterly beautiful.");
console.log("Actually this place has three suns.");
console.log("Where I come from we only had one.");
console.log("That's why we named it "+alien.lives_in_country+".");
console.log("On earth they call it "+alien.lives_on_planet+".");
console.log("This name's utterly ugly.");
console.log("But now I have one problem.");
console.log("This alien loves "+alien.eats+".");
</script>

What do we make of this code? We create two objects, human and alien. But then we assign human to be the prototypal object (__proto__) of alien. That is how alien inherits all properties from human. Alien was a human. Apparently he is no longer such. But if you look closely you will find that he's still human at heart.

One more riddle for you. Which property wasn't defined for John's story? There's one property that wasn't defined verbatim. Which is it? You can also make use of the visualized object:

playing with the proto property of the object, its prototype

Try it out! Type console.dir(alien) into the console and play with the drop down triangles!

The prototypal object (prototype) and inheritance in javascript

Behind the scenes alien inherits from human and human inherits from [object]. Let me prove it to you.

Now we can come back through the backdoor to define what is an object: An object has its own set of properties.

human

name (key) value
name Johann Schmidt
address Königstr. 9
lives_in_city Bonn
lives_in_country Germany
eats beefsteak

alien

name (key) value
name John Smith
address Sunrise boulevard
lives_in_city Sun city
lives_in_country Trisol
lives_on_planet Gliese01228888999

John doesn't know what to eat on the new planet. He must first explore Gliese01228888999. He will eventually explore his coast and his island. Later on one of his descendants (called Christopher) will explore the whole of Gliese01228888999. But as for John the alien, he has not been assigned a property eats. He first has to find out what to eat on Gliese01228888999. So how is it possible we can say console.log("This alien loves "+alien.eats+".") ? The reason is that alien has inherited this property from human. If the property eats is not found with alien, javascript will go down the prototypal staircase and look into the objects below (the other __proto__s). Human has the property eats, so alien too inherits this property. Only problem is that alien will have to find some new kind of food.

Other ways to define an object in javascript

Let's create a new object, using JavaScript Object Notation or JSON. JSON was first specified in the year 2000 by Douglas Crockford. This notation isn't restricted to javascript even though it is derived from javascript. Other computer languages like e.g. C++ have implemented methods to parse JSON. According to Crockford himself "JSON is a light-weight, language independent, data interchange format". JSON is another way to create an object:

<script>

var alive = {
  "firstName": "Johann",
  "lastName": "Schuster",
  "isAlive": true,
  "age": 45,
  "address": {
    "streetAddress": "Königstr.",
    "city": "Bonn",
    "state": "NRW",
    "postalCode": "53111"
  },
  "phoneNumbers": [
    {
      "type": "home",
      "number": "0228 64319"
    },
    {
      "type": "office",
      "number": "0228 74688"
    }
  ],
  "children": [],
  "spouse": null
}
</script>

Now you will see:

Json, a simple object

As we said an object is a set of properties. These properties can be simple name value pairs separated by colons (":").

alive

name (key) value
firstName Johann
lastName Schuster
isAlive true
age 45

But that is not all that is contained in the object alive. It also contains another object: address

name (key) value
streetAddress Königstr.
city Bonn
state NRW
postalCode 53111

Note the difference between a simple property of alive and a simple property of an object contained in alive. An important difference is how to reference these elements of alive:

<script>
console.log("My name is "+alive.firstName+" "+alive.lastName+".");
console.log("I live in "+alive.address.city+" in "+alive.address.streetAddress);
</script>

In console you will see:

referencing an object correctly

And you will find that the property of an object can be another object which is called "nested object".

The prototype property

Building a unique single object

Now that we have talked about objects quite a bit, we should mention a very important way to produce new objects. It is an important method because it can automate the process of production. So let's talk about cars. Big companies don't produce one car, cars are produced in the assembly line to create thousands of them. But let us start slowly. Imagine you have a garage and you want to assemble your very own unique car. First think about the function you want your car to fulfill.

<script>
    function drive() {
      console.log("I am starting my car first.");
      console.log("Vroouuum!!!!");
      console.log("I am accelerating.");
      console.log("I am driving my car now.");  
      console.log("WOOOOSH!!!!");      
    }
</script>

Now you will start building your car.

<script>
var my_car = {}
    my_car.color = "red";
    my_car.speed = "225mph";
</script>

See, your car has no method of how to drive. So you add the method to the object:

<script>
my_car.purpose = drive;
</script>

It is important to see the difference between purpose and purpose(), purpose is only a reference to the function drive, whereas purpose() will execute the function drive(). Lets call it to test my_car:

<script>
my_car.purpose();
</script>

Will give:

how to add a function to an object

Building an object factory with the keyword this

Finally getting productive we can build an object factory:

<script>
function Car (type_of, speed, color){

         this.type_of = type_of;
         this.speed = speed;
         this.color = color;
         this.purpose = drive;

}

var fast_car = new Car ("roadster", "225mph", "red");
var passenger_car = new Car ("passenger", "150mph", "white");
var truck = new Car ("transport", "130mph", "yellow");
</script>

This is a function. It receives three parameters, type_of, speed and color. When this function is called by var fast_car = new Car ("roadster", "225mph", "red") the variable fast_car is created. Three values are handed over to the function Car: "roadster", "225mph" and "red". An object is created toward which the variable fast_car will point. As yet it is still empty. The function Car has got a prototype property as you can see in the object viewer. Try it now and enter into the console: console.dir(Car)!

different objects of different origin and the class - javascript - object viewer of firefox

You can't see it? Open it up:

object in javascript with child object, constructor function Car in object viewer of firefox

Its prototype contains the function Car itself (constructor Car) and the __proto__ Object, the heritage it has received from Object. Play with the console and find out! Now see that the prototypal object (__proto__) of fast_car has the same ingredients as the prototype property of fatherly Car. That is because fast_car's __proto__ points to the prototype property of the function (the constructor function) Car. Change this property and you will change __proto__ of fast_car. Because we used the keyword new in var fast_car = new Car ("roadster", "225mph", "red"), __proto__ is set to the prototype property of the function (the constructor function) Car. The variable this points to the new object fast_car. Here we have a new object whose __proto__ points to the second object (Car), so it's two objects, one Car influencing fast_car during fast_car's birth and fast_car using Car while pointing to Car's prototype property. In this process of production we get fast_car pointing to Car and in this fashion being made of Car. But as yet we have no completed fast_car. What happens next? The constructor function of the newly created object is commanded to do the rest of the work (the same function inherited from Car, so fast_car also has a somewhat hidden constructor function). The variable (or keyword if you like) this points to the current object (fast_car). The reason is because we used the keyword new in the production command var fast_car = new Car ("roadster", "225mph", "red"). After that the surface of the object is created, its main properties are assigned. Because this contains fast_car, you can translate the code like this:

<script>
function Car (type_of, speed, color){

         fast_car.type_of = "roadster";
         fast_car.speed = "225mph";
         fast_car.color = "red";
         fast_car.purpose = drive;

}

var fast_car = new Car ("roadster", "225mph", "red");

</script>

This depends on the variable name you use. If you call var truck = new Car ("transport", "130mph", "yellow") the variable truck will be assigned the new object which will only have "130mph".

The class Car

Inspecting these three objects in the object viewer of firefox, is quite enlightening. A fundamental aspect, though it might be trivial, is that Car exists in memory as a kind of class. It is an important convention to give classes a capital letter. Another aspect which is fundamental is that Car is a function, as it has got a prototype attribute which in turn contains the constructor. See also the prototypal object __proto__: function (). Here you can see that its prototypal object is __proto__: function (). A problem arises through indefinite terminology. It is necessary to keep these two properties apart, the prototypal object __proto__: function () or __proto__: Object and the prototype attribute of the constructor function Car. Mostly both properties are called prototype. This is confusing.

The object my_car

This object is a very simple object. Its prototypal object is __proto__: Object, the archetype. We added color, purpose and speed.

The object fast_car

Our roadster is interesting. Object fast_car inherits from Car.

fast_car.__proto__=== Car.prototype //true

The reason is that when the new object fast_car is created, the prototypal object of the new object fast_car is set to the prototype property of the constructor function Car. So fast_car.__proto__ is pointing to Car.prototype. It is important to understand this relationship between the two objects. If you add something to the prototype property of the constructor function Car, it is automatically implemented in fast_car.

<script>
Car.prototype.elegant = "sexy lines";
console.log(fast_car.elegant);
console.log(passenger_car.elegant);
</script>

Adding properties to the Class will make it available in the object:

the-prototype-property

Also see that all other objects created with Car have this prototypal property pointing to the prototype property of Car. This effects all other objects, so that they too have the property elegant. You can see that even the passenger_car has sexy lines because it likewise has the property elegant. In the viewer of the console you can inspect the outcome of an addition to prototype.

properties added to the prototype of the Car object

See that when you add stuff to the prototype property of Car you add stuff to the __proto__ of fast_car and it then immediately becomes accessible. The difference between the prototype and the __proto__ is that whatever is contained in it can be accessed directly. Access the property elegant for example directly. So it will be:

<script>
console.log(fast_car.elegant); 
</script>

And not necessarily (because possible):

<script>
console.log(fast_car.__proto__.elegant); 
</script>

Or:

<script>
console.log(Car.prototype.elegant); 
</script>

But NOT:

<script>
console.log(Car.elegant); 
</script>

This is the difference.

How to delegate inheritance of objects in javascript

When you think of objects as human beings it is easier to understand the object. Think of the object "Susan". Susan's reproductive organs (ovaries) are removed. The whole reproduction system in inserted from a totally different origin, let's say an Innuit mother. So Susan's mother won't be the real grandmother of Susan's children. The Innuit's mother will be.

<script>

var innuit = {};
        
    innuit.name = "Joan";
    innuit.address = "icicle sunrise";
    innuit.lives_in_city = "iceway";
    innuit.lives_in_country = "Nomansland";
 
</script>

Let's create a Susan-function.

<script>

function Susan () {
	};

	Susan.prototype = innuit;
	her_first_child = new(Susan);
    
</script>

What might have been expected is that Susan's child is a function too. It would have been, if we hadn't set Susan.prototype to innuit. The new child object doesn't inherit from Susan anymore, because her ovaries (Susan.prototype) have been replaced by Joan's ovaries (innuit). She gives birth to the new child, but it's not hers. her_first_child is innuit.

an object has been created by a function


© primitivecode.com





nach oben ↑