Questions on Javascript parasitic inheritance

I’m having a hard time understanding it. I read about it in Ch. 4 of YDKJS - this and Object prototypes.

Here’s the example of parasitic inheritance from the chapter:

// "Traditional JS Class" `Vehicle`
function Vehicle() {
    this.engines = 1;
}
Vehicle.prototype.ignition = function() {
    console.log( "Turning on my engine." );
};
Vehicle.prototype.drive = function() {
    this.ignition();
    console.log( "Steering and moving forward!" );
};

// "Parasitic Class" `Car`
function Car() {
    // first, `car` is a `Vehicle`
    var car = new Vehicle();

    // now, let's modify our `car` to specialize it
    car.wheels = 4;

    // save a privileged reference to `Vehicle::drive()`
    var vehDrive = car.drive;

    // override `Vehicle::drive()`
    car.drive = function() {
        vehDrive.call( this );
        console.log( "Rolling on all " + this.wheels + " wheels!" );
    };

    return car;
}

var myCar = new Car();

myCar.drive();
// Turning on my engine.
// Steering and moving forward!
// Rolling on all 4 wheels!

I start to get lost after car.wheels = 4;. I can see that car.drive is assigned to vehDrive, but…

  1. What is a “privileged reference?” I don’t think Kyle Simpson ever uses that term in previous chapters.

  2. Is it necessary to make that assignment in order to make an explicit this binding in vehDrive.call(this)? If I understand it correctly, this is done so that car's drive method is used instead of vehicle's drive method.

  3. What is the double colon :: operator in the comment Vehicle::drive()?

  4. Please let me know if I understand the last lines of code correctly,

var myCar = new Car();

myCar.drive();

new Car creates a new object, but this object is immediately discarded and the object created by return car is the one that is used. So basically there is no use for new in this situation. The explanation here seems to back my understanding.

edit: I tried to explain what’s happening this code in a blog post. Hopefully it helps someone else, and if you have any suggestions or corrections please let me know!

I’m not an expert on object oriented programing or Javascript but here’s my best shot.

He’s using symbols and terminology common to Object Oriented languages like Java or C++. The :: is called the scope resolution operator, and it’s commonly used to refer to “types” or objects starting from the global scope. In other words…

int number1 = 5;
bool main(void){
  int number1 = 10;
  ::number1 = 0 // This sets the outer number1 from the global scope
}

In this case, it simply refers to the Vehicle “class” outside the scope of the car function. Privilege is similarly referring to how OO languages encapsulate and protect their scopes. Normally, you can’t access a member of another class unless that class explicitly makes it public. If you create a reference to a member of that class you could say that reference has the same “privilege” of the parent class it inherited from.

Javascript doesn’t actually have these “protections”, because it’s a prototyping language and not class based.

Finally, overriding is a term used to describe replacing the original functionality of the parent for a method or member. In this case, var vehDrive = car.drive; is needed because it’s used in the override. He actually “extends” the original drive function.

In the new implementation, he says

// First do everything in Vehicle() drive function
vehDrive.call( this );
// Then also print this out to the console
console.log( "Rolling on all " + this.wheels + " wheels!" );

So new Car creates an object which is not thrown away but rather composed of a modified version of the Vehicle “class”.

Let me know if something in my explanation is confusing and I’d be happy to rephrase.

1 Like
  1. well car is a vehicle, so car.drive is just that function (Vehicle.prototype.drive)
  2. yes making that assignment will change the behavior of ‘this’. If you left out vehDrive and just used car.drive.call(this) it won’t work as the scope is different.
  3. fancy syntax for vehicle.drive()?
  4. myCar is an instance of the Car class. A Car is a Vehicle so it inherits everything, and in addition it has a property called ‘wheels’ which defaults to 4 and a drive method which does everything a Vehicle does plus console.log( “Rolling on all " + this.wheels + " wheels!” ).
1 Like

When you create a new array like
let myArr = [1, 2];
you automatically get property called length. length is now part of myArr and not anything else.
Because it is an array you also get lots of functions like sort() (that are on the prototype) because it is an array.
An array is an object so you also get all the functionality available to you of an object. So if something is added to the proto of array or obj myArr now has direct access to it.
If you call a function like myArr.myFunc();
It will look first in myArr for myFunc - if nothing - then array proto - if nothing - then in obj proto.

And the same works if you start making up object types you can create a proto chain so that it will go up the chain looking for the method.
That way every obj you make doesn’t have to carry every function available it.

Thanks for answering my questions thoroughly! I have a few questions.

So something that is “privileged” is a copy of a certain member from a parent class? Is everything in a child-class privileged? I think the author of this code was doing this earlier, but just never explained the term.

Also, I don’t understand why it’s necessary to make

var vehDrive = car.drive; and then run vehDrive.call(this); instead of just running car.drive.call(this)? Could you please explain that?

Lastly, you said

So new Car creates an object which is not thrown away but rather composed of a modified version of the Vehicle “class”.

However, the author states:

when we call new Car(), a new object is created and referenced by Cars this reference (see Chapter 2). But since we don’t use that object, and instead return our own car object, the initially created object is just discarded.

Thanks for replying!

Could you please explain the difference between vehDrive and car.drive? If vehDrive is just a variable with car.drive stored in it, why do they have a different output when used with .call(this);?

Also, in regards to number 4, I was asking if I’m correct in that the initial object created with the new syntax is discarded and the object created with the line of code return car; is used.

It’s no problem.

“Privileged” is a concept from object oriented languages that doesn’t really apply in Javascript. In Javascript you can inherit (or, more accurately prototype, there is no real inheritance in javascript) whenever you want. In C++ or Java the compiler would throw an error if your class didn’t have the right “privilege” when you try to access a parent class.

This point is not very important, it’s just the authors choice of descriptive vocabulary (from his apparent background in other languages). If you choose to learn about Java or another OO language in the future you’ll cover these topics.

All the author means is “Set a reference to function Car() that has permission to inherit and override members”.

Second, if you look at the full line with your change:

car.drive = function() {
    car.drive.call( this );
    console.log( "Rolling on all " + this.wheels + " wheels!" );
};

you may see the problem. How does the interpreter know which car.drive you mean? The Vehicle() class has a drive method but you just declared a new drive method in your Car() class.

Think about it in terms of variable assignment. car.drive = function (){ means “overwrite whatever is in car.drive with this new function…”

The way prototypical inheritance works is you gain all the methods from your parent object but if you declare an identical method name in the child then yours overwrites the parent. So, var vehDrive = car.drive; saves the pointer to the parent method. This way, when you overwrite it you can still get back to the parent method.

1 Like

I think I get it thanks to your explanation. If we used car.drive.call(this), it would be a recursive function and break. I also tried running that code and that’s the result I got in the console.

Creating the vehVehicle allows to hard code a reference to the original car.drive behavior and incorporate it into the new modified car.drive without making a recursive function. Does that sound right?

By the way, what do you mean when you say “members?” Would that be like an object property or object method in Javascript?

Also, I tried just running this code:

    car.wheels = 4;

    car.drive = function() {
        Vehicle.prototype.drive.call( this );
        console.log( "Rolling on all " + this.wheels + " wheels!" );
    };

Wouldn’t this be more elegant, since it’s less code?

Your understanding is correct.

And I got caught up in the OO language too :cold_sweat:

“Member” functions and variables are what you call methods and variables encapsulated in classes. Like I mentioned, Javascript doesn’t have real classes so it doesn’t have true member variables and functions. It only has objects with properties and methods.

Finally, I would say it’s less elegant for a different reason. One of the “major principles” for OO programming
is encapsulation, which means don’t hard code references to things outside the scope of your function/class/object unless you absolutely have to.

There are lots of reasons that become more clear when you start writing bigger programs. One common example is when you’re asked to write tests for your class.

In real life, function Vehicle() { and function Car() { might be huge classes with tons of methods and properties, lots of complicated calls to APIs, databases, client input etc. To write tests for, say, Car(), it’s common to replace the Vehicle() class with a simple “test dummy” class that inputs predictable values. Normally, you could change out the real Vehicle() by changing

var car = new Vehicle();

to

var car = new TestDummyVehicle();

and everything else would work great… except for your modification which jumped outside the scope of the function and hard-coded a link to Vehicle

1 Like

Alright, thanks again for the explanations :slight_smile:. Your analogy about testing classes was very clear.

This code has been really difficult to get my head around, hopefully when I’m more experienced things will click faster.

No problem :slight_smile:

Don’t let it discourage you, you’re reading pretty advanced stuff. If you’ve made it that far through YDKJS you’re doing well and it will click more with time.

1 Like