In Part 1 of this post we explored the class style paradigm for developing modular code. I encourage reading it before continuing. Its ok if you dont want to, here is the tldr; bullet-point version:
In this post, we will try to understand how we would achieve code re-use similar to Java's Class-based inheritance pattern.
Continuing with our Car example .. if we needed a specialized version we could call it NextGenCar which essentially built upon the existing features. How would we model these requirements where NextGenCar needs the following:
Did the picture help ?
- Classes are not a language construct in JavaScript
- Class-style programming can be simulated because of the language's flexibility
- Function names are capital-cased but the upper-casing is convention-only i.e. to make them look like Java's class constructors.
- var Car = function() {};
- Invoking these functions with the new keyword creates objects/instances
- var myCar = new Car();
- A prototype property exists on all functions. It is an object.
- console.log(Car.prototype); // Object {}
- Code(data/functions) that is meant to be shared across these different instances are added to the prototype property
- Car.prototype.drive = function() { //do stuff };
In this post, we will try to understand how we would achieve code re-use similar to Java's Class-based inheritance pattern.
Continuing with our Car example .. if we needed a specialized version we could call it NextGenCar which essentially built upon the existing features. How would we model these requirements where NextGenCar needs the following:
- Its constructor to re-use Car's constructor and initialize additional instance properties
- Inherit all of Car's features
- to drive more efficiently than the current drive i.e. it needs to extend drive()
- to have a completely overhauled braking system i.e. it needs to override stop()
- to have a way to switch to driverless mode and back
The code solution below is annotated with comments on how each of the above requirement is satisfied
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | var NextGenCar = function(numGears, numWheels){ // #1: Use the call method thats available on functions to mimic super constructor call Car.call(this, numGears); // #1 Initialize additional properties this.numWheels = numWheels; } // #2: Using Car's prototype as blue-print create a new object // and set it as NextGenCar's prototype // so that it inherits all methods of Car via Object [[Prototype]] linkage NextGenCar.prototype = Object.create(Car.prototype); NextGenCar.prototype.drive = function() { //#3: Use the call method to mimix a super call to the method on the "super-class" Car.prototype.drive.call(this); console.log('more for the gallon'); } NextGenCar.prototype.stop = function() { console.log('you said stop and i stopped before you finished saying'); // #4 } // #5: New methods NextGenCar.prototype.switchMode: function(mode){ console.log('cruising in '+mode+' mode'); } var myNextGenCar = new NextGenCar(4, 4); myNextGenCar.switchMode('driverless'); //cruising in driverless mode' |
I think the above code is definitely hard to understand and barely represents what we are trying to do.
Lets see if a picture helps..
(the dotted arrows indicate the prototype linkage between objects)
Did the picture help ?
maybe.. a little bit. But I think this exercise helps realize the futility of attempting class-style programming in a class-less world. There are better alternatives - Object Programming using prototypes and/or functional programming. I will explore the former in my next post.
All that said, it is still useful to understand constructor functions and the prototype property on functions because these are deeply entrenched in the language. There is also a class of problems that can be solved elegantly using ES6 classes only and not using the alternatives mentioned above (and this will be a topic of a blog post for an other day)
All that said, it is still useful to understand constructor functions and the prototype property on functions because these are deeply entrenched in the language. There is also a class of problems that can be solved elegantly using ES6 classes only and not using the alternatives mentioned above (and this will be a topic of a blog post for an other day)

No comments:
Post a Comment