JavaScript Jems - The Inheritance Tax |
Written by Mike James | |||||
Tuesday, 09 April 2024 | |||||
Page 4 of 4
Inheritance and ExtendsAs repeatedly stated, JavaScript doesn't have class-based inheritance and doesn't have a hierarchical type system, despite attempts to add both. You can regard a prototype object as being a "base object" that the "derived object" inherits from, and sometimes this is a realistic thing to do. At other times, the prototype is just a way of sharing code between multiple objects. In fact, most of the time code sharing is the motivation for using the prototype. To make the prototype look more like class based inheritance ES2015 introduced the extends keyword: class B extends A{ constructor() { super(); ... } which makes it look as if inheritance is in play. Again, however, this is syntactic sugar, but of a slightly higher order than we have encountered so far. The reason is that we want class B to have all of the properties and methods of class A before we start adding to it or modifying it. The problem is that class A has its own properties and methods, as well as those of its prototype object. In JavaScript inheritance involves two objects not one. The key to understanding what is going on is to realize that the extends keyword sets class B's prototype to include A's prototype in its prototype chain. So extends A is equivalent to: B.prototype = Object.create(A.prototype); This makes B's prototype a null object which has A's prototype as its prototype. This allows new methods to be added to the null object without modifying A's prototype. After this step B also has all of the properties and methods provided to A by its prototype chain. We now have to deal with A's own properties and to inherit these we have to use the super function call, which will call any method of the base object using super.baseFunctionName(). If you call it without specifying the function you are calling, the base class constructor is called and the result is set to this. That is super() is equivalent to: this=new A(); This means that the new class B has all of the methods and properties of class A defined directly before you start adding to them. In this sense a class B object really does start out as a class A object. Notice that you can pass parameters to the base class constructor and, if you don't want the owned properties to be inherited, then you can avoid calling super. At this point class B has all of the properties and methods, both its own and those provided by the prototype, of class A. This is how you can implement something like class-based inheritance in JavaScript with or without the new class, extends and super keywords of ES2015. Is Class Harmful?JavaScript, specifically ES2015, has class in name only as it is still an object-centric language. Does the attempt to import the idea of class into it matter? Is it just a syntactic ploy to simplify and make object creation seem more like what the majority of programmers are familiar with? There is a sense in which this is true, but there are some negative effects. If you think in terms of class there is a tendency to see objects that have the same properties and methods as somehow being related or worse, "the same". In JavaScript every object is a singleton and not an instance of some class. Each object has its own copy of the data and the code that operates on it, unless you go to a little effort to share the code. And more to the point, things that look like classes are in fact objects that are object factories. Covering up how things work is likely to lead to subtle and very difficult-to-find bugs. A typical, though obvious, error caused by focusing on class is when two different objects that just happen to have the same properties and methods are are used as the prototype for another set of objects. Clearly only one of the two should be used as the prototype, but thinking of them as instances of a class makes them seem interchangeable. Similar mistakes are often more subtle than this. In JavaScript there are only objects and every object is a singleton. This jem means that JavaScript is simple and direct in its approach to objects, but it also demands that you understand and use the facilities correctly.
Now available as a book from your local Amazon.JavaScript Jems:
|
|||||
Last Updated ( Wednesday, 10 April 2024 ) |