One of the major advantages with Javascript is said to be that it is a prototype based language.
But what does it mean that Javascript is prototype based, and why is that an advantage?
Prototypal inheritance is a form of object-oriented code reuse. Javascript is one of the only [mainstream] object-oriented languages to use prototypal inheritance. Almost all other object-oriented languages are classical.
In classical inheritance, the programmer writes a class, which defines an object. Multiple objects can be instantiated from the same class, so you have code in one place which describes several objects in your program. Classes can then be organized into a hierarchy, furthering code reuse. More general code is stored in a higher-level class, from which lower level classes inherit. This means that an object is sharing code with other objects of the same class, as well as with its parent classes.
In the prototypal inheritance form, objects inherit directly from other objects. All of the business about classes goes away. If you want an object, you just write an object. But code reuse is still a valuable thing, so objects are allowed to be linked together in a hierarchy. In javascript, every object has a secret link to the object which created it, forming a chain. When an object is asked for a property that it does not have, its parent object will be asked... continually up the chain until the property is found or until the root object is reached.
Each function in JavaScript (which are objects themselves) actually has a member called "prototype", which is responsible for providing values when an object is asked for them. Having this member allows the constructor mechanism (by which objects are constructed from functions) to work. Adding a property to the prototype of a function object will make it available to the constructed object, as well as to all of the objects which inherit from it.
Advantages
There may not be a hard and fast rule as to why prototypal inheritance is an advantageous form of code-reuse. Code reuse itself is advantageous, and prototypal inheritance is a sensible way of going about it. You might argue that prototypal inheritance is a fairly simple model of code reuse, and that code can be heavily reused in direct ways. But classical languages are certainly able to accomplish this as well.
Sidenote: #Andrew Hedges makes a good point, that there are actually many prototypal languages. It's worth noting that these others exist, but also worth noting that none of them are anything close to mainstream. NewtonScript seemed to have some traction for a while, but died with its platform. It's also possible to extend some modern languages in ways which add prototypal capabilities.
A prototype-based language, does not make the distinction of classes vs objects: it simply has objects. A prototype-based language has the notion of a prototypical object, an object used as a template from which to get the initial properties for a new object. Any object can specify its own properties, either when you create it or at run time. In addition, any object can be associated as the prototype for another object, allowing the second object to share the first object's properties.
Prototype-based programming is a style of object-oriented programming where classes are not present, and behavior reuse (or inheritance in class-based languages) is performed by cloning existing objects that serve as prototypes.
The advantage/disadvantage is that, we can create new kinds of objects at run time without need for defining classes (static code). Like most features it is upto the developer to turn it to a advantage/disadvantage.
Above is possible because objects are essentially functions in java script (closures too).
Instead of declaring a class structure, you can create objects of the same type, and add to their definition any time you like using the object's prototype.
It's more flexible than the normal way of doing things.
After reading all the answers this is the conclusion
1) Inheritance in which objects are inherited directly from other objects
2) That does not use classes
3) Also called instance based programming or classless prototype oriented programming
4) Behaviour reuse is performed by cloning existing objects that serve as prototypes
5) Object used as template from the new object get initial properties
If you just use objects at runtime instead of a class at compile to build new objects, this opens up the possibility of extending an object without knowing any details about it. Of course, it may become a disadvantage pretty quickly depending on usage. I make no assumptions about the language here, so it is applicable to languages other than javascript which are not as dynamic.
myobject.prototype=unkownobject;
myobject.newproperty=1;
You may get the object from just about anywhere; your own code, from the network, from the database, from external linkage and so on.
Note that, a language don't have to implement prototype inheritance like javascript. In javascript, a prototype object is merely shared, so is its properties, among the inheritors. The alternative is copying over all the properties of the prototype to the new object. Each approach has its strengths in different situations. I like the second more but it isn't what javascript does.
Memory conservation is one of the benefits of prototypal inheritance in JS. In a language like Java, objects generate their own copies of the superclass' instance variables and methods, while in JS, the "super"-object offers get-access to its variables and methods to each "sub"-object that inherits from it without the need to recreate them.
Related
For the past week I've been trying to understand the difference between class based and prototypical inheritance. Having worked with PHP and JavaScript, I expected to grasp this rather quickly, but I just can't wrap my head around this – I always have the feeling that I miss something.
I've learned that a class is like a blueprint defining an object's characteristics. When a class is instantiated, an object is constructed according to the blueprint. When inheritance comes into play, the blueprint can only be adopted completely but methods can be overridden.
But what is a prototype then? Isn't it also like a blueprint, but already implemented (hence the name "prototype")? So with inheritance, you can only point to already existing functions?
The following may seem silly but thats the way I try to understand things.
In more human terms: A class can be regarded as architectural plan, as soon as it get's instantiated small workers start building an object according to that plan. To inherit something, the complete plan is built again, in addition to new details (that may replace existing details).
With prototypes, the workers instead start copying an already existing object and start looking at it's main characteristics (stored on something called the prototype). To inherit from another object, they just put a sign somewhere saying "You are looking for function X? Please this way – mind the gap between objects".
Is this distinction correct?
It seems to me that you actually already got the point.
Class based OO
As you already mentioned, in class-based object oriented languages (like Java) a class is a blueprint for every future object. For the instantiation of an object the blueprint (the class you created) gets copied for this object. This means that in case you change the class after you instantiate your object the previously created object won't have that changes.
When it comes to inheritance: Let's say you have a class Person. You want to create another class Student that inherits from Person. Student is basically a copy of the blueprint Person which can extend the functionality of the blueprint. So your example is very accurate!
This is very useful in complex but rather static OO-structures!
Prototype based
Prototype based languages like JavaScript don't follow this templating kind of approach. Your example hit it pretty good again. You basically just create an object and reference to another object (your prototype). All the functionality you put in your prototype will be shared by all the objects that reference to that prototype object. However, it is important to understand that you don't make copies of blueprints or templates. You are always working with objects.
So you could create a Person Object. That holdsmethods like "sayHello". If you create concrete person e.g. Joe you just create another object and link it to the Person object. So if you try Joe.sayHello() it will look through the Joe object properties and won't find the sayHello method so it will jump over to the concrete Person object. Just like you said with your example.
I don't really like the expression inheritance in prototype based languages because it does not really exist. You don't make a copy of a blueprint and extend its functionality. Inheritance basically works by chaining objects together. For instance the example above. You can have a Person object. Every regular person object (e.g. Joe) has the Person Object as a prototype. Now you create a Student object which has the Person as a prototype. Another object (e.g. StudentJoe) can have Student as a prototype. So it can go through the chain all the way up to person to access its methods.
To keep it short ;): prototype based languages only work with concrete objects which are linked together (prototypes) and not with blue prints and templates.
The advantage of this approach is being dynamic (that's why this approach is commonly used in the web). As you never work with templates but with concrete objects every change in the prototype-chain will always have effect on every object (in terms of accessable functionality) - no matter when it was created.
I hope this helped. There is a good book called You don't know JavaScript - this & object prototype which explains this topic based on JavaScript really well.
In JavaScript, every object is at the same time an instance and a class. To do inheritance, you can use any object instance as a prototype.
In Python, C++, etc.. there are classes, and instances, as separate concepts. In order to do inheritance, you have to use the base class to create a new class, which can then be used to produce derived instances.
Why did JavaScript go in this direction (prototype-based object orientation)? what are the advantages (and disadvantages) of prototype-based OO with respect to traditional, class-based OO?
There are about a hundred terminology issues here, mostly built around someone (not you) trying to make their idea sound like The Best.
All object oriented languages need to be able to deal with several concepts:
encapsulation of data along with associated operations on the data, variously known as data members and member functions, or as data and methods, among other things.
inheritance, the ability to say that these objects are just like that other set of objects EXCEPT for these changes
polymorphism ("many shapes") in which an object decides for itself what methods are to be run, so that you can depend on the language to route your requests correctly.
Now, as far as comparison:
First thing is the whole "class" vs "prototype" question. The idea originally began in Simula, where with a class-based method each class represented a set of objects that shared the same state space (read "possible values") and the same operations, thereby forming an equivalence class. If you look back at Smalltalk, since you can open a class and add methods, this is effectively the same as what you can do in Javascript.
Later OO languages wanted to be able to use static type checking, so we got the notion of a fixed class set at compile time. In the open-class version, you had more flexibility; in the newer version, you had the ability to check some kinds of correctness at the compiler that would otherwise have required testing.
In a "class-based" language, that copying happens at compile time. In a prototype language, the operations are stored in the prototype data structure, which is copied and modified at run time. Abstractly, though, a class is still the equivalence class of all objects that share the same state space and methods. When you add a method to the prototype, you're effectively making an element of a new equivalence class.
Now, why do that? primarily because it makes for a simple, logical, elegant mechanism at run time. now, to create a new object, or to create a new class, you simply have to perform a deep copy, copying all the data and the prototype data structure. You get inheritance and polymorphism more or less for free then: method lookup always consists of asking a dictionary for a method implementation by name.
The reason that ended up in Javascript/ECMA script is basically that when we were getting started with this 10 years ago, we were dealing with much less powerful computers and much less sophisticated browsers. Choosing the prototype-based method meant the interpreter could be very simple while preserving the desirable properties of object orientation.
A comparison, which is slightly biased towards the prototypes based approach, can be found in the paper Self: The Power of Simplicity. The paper makes the following arguments in favor of prototypes:
Creation by copying. Creating new objects from prototypes is accomplished by a simple operation, copying, with a simple biological
metaphor, cloning. Creating new objects from classes is accomplished
by instantiation, which includes the interpretation of format
information in a class. Instantiation is similar to building a house
from a plan. Copying appeals to us as a simpler metaphor than
instantiation.
Examples of preexisting modules. Prototypes are more concrete than classes because they are examples of objects rather than descriptions
of format and initialization. These examples may help users to reuse
modules by making them easier to understand. A prototype-based system
allows the user to examine a typical representative rather than
requiring him to make sense out of its description.
Support for one-of-a-kind objects. Self provides a framework that can easily include one-of-a-kind objects with their own behavior.
Since each object has named slots, and slots can hold state or
behavior, any object can have unique slots or behavior. Class-based
systems are designed for situations where there are many objects with
the same behavior. There is no linguistic support for an object to
possess its own unique behavior, and it is awkward to create a class that is guaranteed to have only one
instance [think singleton
pattern]. Self suffers from neither of these disadvantages. Any object
can be customized with its own behavior. A unique object can hold the
unique behavior, and a separate "instance" is not needed.
Elimination of meta-regress. No object in a class-based system can be self-sufficient; another object (its class) is needed to express
its structure and behavior. This leads to a conceptually infinite
meta-regress: a point is an instance of class Point, which is an
instance of metaclass Point, which is an instance of metametaclass
Point, ad infinitum. On the other hand, in prototype-based systems
an object can include its own behavior; no other object is needed to
breathe life into it. Prototypes eliminate meta-regress.
Self is probably the first language to implement prototypes (it also pioneered other interesting technologies like JIT, which later made its way into the JVM), so reading the other Self papers should also be instructive.
You should check out a great book on JavaScript by Douglas Crockford. It provides a very good explanation of some of the design decisions taken by JavaScript creators.
One of the important design aspects of JavaScript is its prototypal inheritance system. Objects are first class citizens in JavaScript, so much that regular functions are also implemented as objects ('Function' object to be precise). In my opinion, when it was originally designed to run inside a browser, it was meant to be used to create lots of singleton objects. In browser DOM, you find that window, document etc all singleton objects. Also, JavaScript is loosely typed dynamic language (as opposed to say Python which is strongly typed, dynamic language), as a result, a concept of object extension was implemented through the use of 'prototype' property.
So I think there are some pros for prototype-based OO as implemented in JavaScript:
Suitable in loosely typed environments, no need to define explicit types.
Makes it incredibly easy to implement singleton pattern (compare JavaScript and Java in this regard, and you'll know what I am talking about).
Provides ways of applying a method of an object in the context of a different object, adding and replacing methods dynamically from an object etc. (things which are not possible in a strongly typed languages).
Here are some of the cons of prototypal OO:
No easy way of implementing private variables. Its possible to implement private vars using Crockford's wizardry using closures, but its definitely not as trivial as using private variables in say Java or C#.
I don't know how to implement multiple inheritances (for what its worth) in JavaScript yet.
The difference between mainstream OOP class-based languages such as c# or java and prototype bases languages such as javascript is the ability to modify object types at runtime whilst in c# or java they gave up this ability in favor of static type checking by making classes fixed at compile time. JS has always been closer to the first original design of OOP of alan Kay and languages such as Smalltalk or simula.
this is achieved by making the blueprint itself an instance, types in prototype-based are actual instances that can be accessed and modified at runtime, in Javascript this is really easy using the prototype object, since every object type has this object.
example: type funcName.prototype.myNewMethod= function{ console.log("hello world")}
Javascript lacks a class construct, however you can still achieve inheritance many different ways.
You can mimic classes by utilizing prototypes to create constructor functions and thus implementing inheritance via delegation.
The most common way to do this is with the new keyword, but you can also implement object.create().
Alternatively, you can take a concatenative approach and copy behavior that you want your object to inherit directly into the object itself, rather than by pointing its [[prototype]] to another object.
What are the advantages and drawbacks of each pattern in JS?
It seems many experts are advocating the concatenative approach, like Doug Crockford for example. The delegation pattern is clearly more popular at the moment, however.
I know that, in general, the concatenative approach is going to be more flexible, but will consume more memory because your copying methods all over the place rather than just referencing a common set.
However, I also know that the V8 engine has ways of optimizing this stuff.
Besides performance, is there anything that you can achieve via delegation that you can achieve via concatenation? For example, in delegation, I can have a method in a super class that implements some basic functionality and in my subclass methods I can call the super's method and then do some subclass-specific computations before returning the final result. I can't think of a way to do this with the concatenative approach without just using a different method name.
The main differences are object size and flexibility. Inheriting properties instead of copying them will lead to smaller objects, especially if your method API is relatively large. Also, inheriting properties from a single object that can still be manipulated is much more dynamic (see Does some JavaScript library use dynamic aspects of the prototype system?). It might be more complicated to optimize than inheriting from static objects, but it is still faster than not sharing between objects.
I am reading a book about JS and other web stuff now and that's what I encountered about the prototype keyword:
The prototype keyword can save you a lot of memory. In the User class, every instance will contain the three properties and the method. Therefore, if you have 1,000 of these objects in memory, the method showUser will also be replicated 1,000 times. However, because the method is identical in every case, you can specify that new objects should refer to a single instance of the method instead of creating a copy of it.
Don't any object-oriented language behaves just like this? I have read some books about C++, C# and never been told about that. I think it follows to create static methods in class and call them from not static methods, or it is not a problem in other languages and I should not even remember about that?
In C# and other statically typed langauges, the methods each class users are defined once and then each instantiation of that object refers only to the single definition. As such, there is no need for the same construct as the prototype in JS.
Prototypes is a very different way of doing OOP.
With this paradigm, objects contain both code and data. That's why if you duplicate your objects thousands of times, there will be thousands of copies of the methods. In the more common inheritance paradigm, classes only have a reference to their methods, the method is outside the objects.
Very few languages follow this paradigm, but Javascript is one of them. Most OOP languages, like C# or C++, don't have the kind of prototypes you're talking about, so they don't have this particular problem.
In JavaScript, every object is at the same time an instance and a class. To do inheritance, you can use any object instance as a prototype.
In Python, C++, etc.. there are classes, and instances, as separate concepts. In order to do inheritance, you have to use the base class to create a new class, which can then be used to produce derived instances.
Why did JavaScript go in this direction (prototype-based object orientation)? what are the advantages (and disadvantages) of prototype-based OO with respect to traditional, class-based OO?
There are about a hundred terminology issues here, mostly built around someone (not you) trying to make their idea sound like The Best.
All object oriented languages need to be able to deal with several concepts:
encapsulation of data along with associated operations on the data, variously known as data members and member functions, or as data and methods, among other things.
inheritance, the ability to say that these objects are just like that other set of objects EXCEPT for these changes
polymorphism ("many shapes") in which an object decides for itself what methods are to be run, so that you can depend on the language to route your requests correctly.
Now, as far as comparison:
First thing is the whole "class" vs "prototype" question. The idea originally began in Simula, where with a class-based method each class represented a set of objects that shared the same state space (read "possible values") and the same operations, thereby forming an equivalence class. If you look back at Smalltalk, since you can open a class and add methods, this is effectively the same as what you can do in Javascript.
Later OO languages wanted to be able to use static type checking, so we got the notion of a fixed class set at compile time. In the open-class version, you had more flexibility; in the newer version, you had the ability to check some kinds of correctness at the compiler that would otherwise have required testing.
In a "class-based" language, that copying happens at compile time. In a prototype language, the operations are stored in the prototype data structure, which is copied and modified at run time. Abstractly, though, a class is still the equivalence class of all objects that share the same state space and methods. When you add a method to the prototype, you're effectively making an element of a new equivalence class.
Now, why do that? primarily because it makes for a simple, logical, elegant mechanism at run time. now, to create a new object, or to create a new class, you simply have to perform a deep copy, copying all the data and the prototype data structure. You get inheritance and polymorphism more or less for free then: method lookup always consists of asking a dictionary for a method implementation by name.
The reason that ended up in Javascript/ECMA script is basically that when we were getting started with this 10 years ago, we were dealing with much less powerful computers and much less sophisticated browsers. Choosing the prototype-based method meant the interpreter could be very simple while preserving the desirable properties of object orientation.
A comparison, which is slightly biased towards the prototypes based approach, can be found in the paper Self: The Power of Simplicity. The paper makes the following arguments in favor of prototypes:
Creation by copying. Creating new objects from prototypes is accomplished by a simple operation, copying, with a simple biological
metaphor, cloning. Creating new objects from classes is accomplished
by instantiation, which includes the interpretation of format
information in a class. Instantiation is similar to building a house
from a plan. Copying appeals to us as a simpler metaphor than
instantiation.
Examples of preexisting modules. Prototypes are more concrete than classes because they are examples of objects rather than descriptions
of format and initialization. These examples may help users to reuse
modules by making them easier to understand. A prototype-based system
allows the user to examine a typical representative rather than
requiring him to make sense out of its description.
Support for one-of-a-kind objects. Self provides a framework that can easily include one-of-a-kind objects with their own behavior.
Since each object has named slots, and slots can hold state or
behavior, any object can have unique slots or behavior. Class-based
systems are designed for situations where there are many objects with
the same behavior. There is no linguistic support for an object to
possess its own unique behavior, and it is awkward to create a class that is guaranteed to have only one
instance [think singleton
pattern]. Self suffers from neither of these disadvantages. Any object
can be customized with its own behavior. A unique object can hold the
unique behavior, and a separate "instance" is not needed.
Elimination of meta-regress. No object in a class-based system can be self-sufficient; another object (its class) is needed to express
its structure and behavior. This leads to a conceptually infinite
meta-regress: a point is an instance of class Point, which is an
instance of metaclass Point, which is an instance of metametaclass
Point, ad infinitum. On the other hand, in prototype-based systems
an object can include its own behavior; no other object is needed to
breathe life into it. Prototypes eliminate meta-regress.
Self is probably the first language to implement prototypes (it also pioneered other interesting technologies like JIT, which later made its way into the JVM), so reading the other Self papers should also be instructive.
You should check out a great book on JavaScript by Douglas Crockford. It provides a very good explanation of some of the design decisions taken by JavaScript creators.
One of the important design aspects of JavaScript is its prototypal inheritance system. Objects are first class citizens in JavaScript, so much that regular functions are also implemented as objects ('Function' object to be precise). In my opinion, when it was originally designed to run inside a browser, it was meant to be used to create lots of singleton objects. In browser DOM, you find that window, document etc all singleton objects. Also, JavaScript is loosely typed dynamic language (as opposed to say Python which is strongly typed, dynamic language), as a result, a concept of object extension was implemented through the use of 'prototype' property.
So I think there are some pros for prototype-based OO as implemented in JavaScript:
Suitable in loosely typed environments, no need to define explicit types.
Makes it incredibly easy to implement singleton pattern (compare JavaScript and Java in this regard, and you'll know what I am talking about).
Provides ways of applying a method of an object in the context of a different object, adding and replacing methods dynamically from an object etc. (things which are not possible in a strongly typed languages).
Here are some of the cons of prototypal OO:
No easy way of implementing private variables. Its possible to implement private vars using Crockford's wizardry using closures, but its definitely not as trivial as using private variables in say Java or C#.
I don't know how to implement multiple inheritances (for what its worth) in JavaScript yet.
The difference between mainstream OOP class-based languages such as c# or java and prototype bases languages such as javascript is the ability to modify object types at runtime whilst in c# or java they gave up this ability in favor of static type checking by making classes fixed at compile time. JS has always been closer to the first original design of OOP of alan Kay and languages such as Smalltalk or simula.
this is achieved by making the blueprint itself an instance, types in prototype-based are actual instances that can be accessed and modified at runtime, in Javascript this is really easy using the prototype object, since every object type has this object.
example: type funcName.prototype.myNewMethod= function{ console.log("hello world")}