The Difference Between Classes (Like In Ruby) And Prototypes (Like In JavaScript)
posted on November 9, 2015
Jump To Section....
The differences and similarities...
My previous blog post demonstrated classes in Object-Oriented programming (by using Ruby). This week at Dev Bootcamp, the material covered JavaScript. JavaScript, like Ruby, IS an Object-Oriented language. Hell, their "hashes"/"dictionaries" (for you Python folks out there) are literally called objects
. JavaScript (or JS for short) has tools that allow the code to be more modular, has "A PIE", which is a mnemonic that stands for Abstraction, Polymorphism, Inheritance, and Encapsulation. But JavaScript is unusual among programming languages in that it does not have true classes. It is a class-less language. Meaning, that it is not a "class-based" Object-Oriented language, but a prototypal-based Object Oriented language.
This basically means that instead of using a class as a blueprint for an instance of an object, JS uses objects that have constructors
to initialize new objects. How are constructors different from classes? In class-based languages, the class would have something to initialize the class. All Java classes have an init
method. All Ruby classes need an initialize
method.
JS constructors don't need one. For this reason, in JS, every function is potentially a constructor. In languages that have classes like Ruby, classes are special kinds of objects that create new instances. JS does not have things like these, but they have prototypes. Prototypes are objects, but they don't have special methods or properties specifically associated with it. Literally any object in JS can be a prototype.
Basically in prototype-based languages, there is no distinction between instances of an object. A good way to demonstrate these are through examples:
# Classical Inheritance With Ruby: class ExampleSuperclass def initialize @my_local_variable_1 @my_local_variable_2 end def my_getter_method @my_local_variable_1 end def my_setter_method(my_argument) @my_local_variale_1 = my_argument end end class ExampleSubclass < ExampleSuperclass # the "lesser than" lets ExampleSubclass inherit from ExampleSuperclass def initialize @my_local_variable_1 @my_local_variable_2 end def some_method #whatever code end end # instantiating objects w/ class-based language: new_thing = ExampleSuperclass.new another_thing = ExampleSubcleass.new
// Prototypal Inheritance With JavaScript: function ExampleSuper() { this.myLocalVariable1; this.myLocalVariable2; this.my_getter_method = function() { this.myLocalVariable1; } this.my_setter_method = function(My_argument) { this.myLocalVariable1 = my_argument; } } var ExampleSub = function() { ExampleSuper.call(this); // this line allows inheritance from ExampleSuper this.someMethod { //whatever code } } ExampleSub.prototype = Object.create(ExampleSuper.prototype); // instantiating objects with prototype-based language: var new_thing = new ExampleSub;
I hope that was sufficient to explain the similarities and differences. The main deal with prototypal-based languages is that objects inherit directly from other objects, whereas in class-based languages, objects are instances of a class, and classes inherit from their superclass/base class. As you can imagine, prototypal languages have advantages and disadvantages (same with class-based languages). Below, I've provided links to work that have explained these concepts more eloquently than I have.
Additional References And Resources
developer.mozilla.org ~ Details of the object model
raganwald.com ~ Classes vs. Prototypes In JavaScript
ncl.ucar.edu ~ Understanding classes and objects
Wikipedia ~ Prototype-based programming
javascriptissexy.com ~ JavaScript Prototype in Plain Language
StackExchange ~ What are the advantages of prototype-based OOP over class-based OOP?
Stack Overflow ~ What does it mean that JavaScript is a prototype based language?