My early experiences with JavaScript began with version 1.0. It was a fantastic and wild time. Tons of mouseOver and scrolling banners. The world was great. Developers were learning, sharing, and inventing clever hacks to do amazing things in the browser. At the same time I was nose deep in this other fledgling language named Java. Java and JavaScript: two languages sharing a common base name, but with vast differences in their implementations of inheritance. Java supports object inheritance. Java uses the extends keyword to refine the definition of a type into a subtype. I got it. At the time my hope was for a similar concept in JavaScript. I was wrong. Instead of Java-style inheritance, I was left with fuzzy words like prototype and methods like .apply(). I was unhappy. JavaScript can provide inheritance and class hierarchy like Java, but it is done differently. First steps first: Prototype. Most implementations of inheritance in JavaScript are based on prototypes. Technically, prototypes are not “doing” inheritance, they are a tool to make us feel like there is inheritance – a discussion on prototypes is not necessarily a discussion about inheritance. So we will figure out prototypes first, and then let the application of this concept lead to inheritance later. JavaScript objects are critical. Objects contain properties and methods.
<script language="JavaScript"> var driverslicense1 = {firstname :"Delois", lastname:"Price", show:function(){ console.log("Licensee: "+this.firstname + " " + this.lastname)} }; driverslicense1.show(); </script>
The single object instantiated above has three properties, one being a function. Creating a second object with a very similar structure makes OO developers everywhere cringe:
<script language="JavaScript"> var driverslicense1 = {firstname :"Delois", lastname:"Price", show:function(){ console.log("Licensee: " + this.firstname + " " + this.lastname)} }; driverslicense1.show(); var driverslicense2 = {firstname :"Michael", lastname:"Bolton", show:function(){ console.log("Licensee: " + this.firstname + " " + this.lastname)} }; driverslicense2.show(); </script>
The function is repeated because the base JavaScript does not include our version of show(). This is one place where prototypes can be helpful. Every object in JavaScript is automatically and implicitly assigned a prototype object. JavaScript objects have an implicit variable named __proto__ .
The prototype object becomes an entry in the “search path” for properties. If a property is trying to be resolved on an object and it is not found, JavaScript will look at that object’s prototype and try to resolve it there. So properties are first resolved in the actual object, and then in the prototype.
<script language="JavaScript"> var driverslicense1 = {firstname :"Delois", lastname:"Price"}; driverslicense1.__proto__.show = function(){ console.log("Licensee: "+this.firstname + " " + this.lastname); } driverslicense1.show(); </script>
In the code above, the show() function was removed from the actual object and added to the prototype for that object. When we tried to execute the show() function, JavaScript searched the object first for the function, and then the prototype for that object. The prototype is now responsible for providing the show() function. The Prototype object is just an object. It can be treated like any other object. It can be modified or it can be created from scratch. JavaScript will automatically create a prototype when you create an object, but we can choose to create our own object and assign it to the __proto__ property. By creating our own object, we have a bit more explicit control of the properties included. The following example creates a new object and assigns it to the __proto__ property of the driverslicense1 object:
<script language="JavaScript"> var driverslicense1 = {firstname :"Delois", lastname:"Price"}; driverslicense1.__proto__={show :function(){ console.log("Licensee: " + this.firstname + " " + this.lastname); }} driverslicense1.show(); </script>
Creating our own prototype lets us use any object as the prototype. The realization that __proto__ is just a normal object and we are able to do normal “object” stuff with it allows us to use it to solve the earlier code reuse problem. In the example below, we simply assign the prototype from driverlicense1 to the __proto__ property of driverslicense2. Now both instances of the driverslicense can share the implementation of the show method.
<script language="JavaScript"> var driverslicense1 = {firstname :"Delois", lastname:"Price"}; driverslicense1.__proto__={show :function(){ console.log("Licensee: " + this.firstname + " " + this.lastname); }} driverslicense1.show(); var driverslicense2 = {firstname :"Michael", lastname:"Bolton"}; driverslicense2.__proto__= driverslicense1.__proto__; driverslicense2.show(); </script>
Of course if driverslicense2 happened to have its own property named show, then JavaScript would resolve that property first and not use the “inherited” version of show that would have come from the prototype. In our example, the driverslicense1 prototype becomes a very powerful object for sharing properties across objects of a similar type. This concept is used very heavily when JavaScript is used to define an OO model using Constructors and inheritance. Keep an eye open for more on JavaScript Prototype Inheritance.
Author: Todd Wright, one of Accelebrate’s instructors Accelebrate offers private JavaScript training for groups and instructor-led online JavaScript classes for individuals.
Written by Todd Wright
We offer private, customized training for 3 or more people at your site or online.
Our live, instructor-led lectures are far more effective than pre-recorded classes
If your team is not 100% satisfied with your training, we do what's necessary to make it right
Whether you are at home or in the office, we make learning interactive and engaging
We accept check, ACH/EFT, major credit cards, and most purchase orders
Alabama
Birmingham
Huntsville
Montgomery
Alaska
Anchorage
Arizona
Phoenix
Tucson
Arkansas
Fayetteville
Little Rock
California
Los Angeles
Oakland
Orange County
Sacramento
San Diego
San Francisco
San Jose
Colorado
Boulder
Colorado Springs
Denver
Connecticut
Hartford
DC
Washington
Florida
Fort Lauderdale
Jacksonville
Miami
Orlando
Tampa
Georgia
Atlanta
Augusta
Savannah
Hawaii
Honolulu
Idaho
Boise
Illinois
Chicago
Indiana
Indianapolis
Iowa
Cedar Rapids
Des Moines
Kansas
Wichita
Kentucky
Lexington
Louisville
Louisiana
New Orleans
Maine
Portland
Maryland
Annapolis
Baltimore
Frederick
Hagerstown
Massachusetts
Boston
Cambridge
Springfield
Michigan
Ann Arbor
Detroit
Grand Rapids
Minnesota
Minneapolis
Saint Paul
Mississippi
Jackson
Missouri
Kansas City
St. Louis
Nebraska
Lincoln
Omaha
Nevada
Las Vegas
Reno
New Jersey
Princeton
New Mexico
Albuquerque
New York
Albany
Buffalo
New York City
White Plains
North Carolina
Charlotte
Durham
Raleigh
Ohio
Akron
Canton
Cincinnati
Cleveland
Columbus
Dayton
Oklahoma
Oklahoma City
Tulsa
Oregon
Portland
Pennsylvania
Philadelphia
Pittsburgh
Rhode Island
Providence
South Carolina
Charleston
Columbia
Greenville
Tennessee
Knoxville
Memphis
Nashville
Texas
Austin
Dallas
El Paso
Houston
San Antonio
Utah
Salt Lake City
Virginia
Alexandria
Arlington
Norfolk
Richmond
Washington
Seattle
Tacoma
West Virginia
Charleston
Wisconsin
Madison
Milwaukee
Alberta
Calgary
Edmonton
British Columbia
Vancouver
Manitoba
Winnipeg
Nova Scotia
Halifax
Ontario
Ottawa
Toronto
Quebec
Montreal
Puerto Rico
San Juan