Search code examples
javascriptoopinheritanceprototype

JavaScript returning 'undefined' when calling prototype member


So I'm new to OOP in JavaScript and having trouble understanding why I'm getting 'undefined' in the following code, please help:

function Vehicle(energyType, energy) {
	this.energyType = energyType;
	this.energy = energy;
}

function Car(energyType, energy) {
	Vehicle.call(energyType, energy);

	this.doors = 4;
}

Car.prototype = Object.create(Vehicle.prototype);

Vehicle.prototype.run = function() {
	console.log(`This vehicle is running on ${this.energyType}.`);
}

const c = new Car('gas', 80);

c.run();

When you run the code it says "This vehicle is running on undefined" even though I said Car had gas energyType...?


Solution

  • When you .call, the first argument should be the this you want the called function to refer to. So,

    Vehicle.call(energyType, energy);
    

    results in Vehicle being called with one parameter, with the this value being what was initially the energyType variable (coerced into an object, because this has to be an object, not a primitive). You can see this if you console.log inside Vehicle:

    function Vehicle(energyType, energy) {
      console.log('this', this);
      console.log('energyType', energyType);
      console.log('energy', energy);
    	this.energyType = energyType;
    	this.energy = energy;
    }
    
    function Car(energyType, energy) {
    	Vehicle.call(energyType, energy);
    
    	this.doors = 4;
    }
    
    Car.prototype = Object.create(Vehicle.prototype);
    
    Vehicle.prototype.run = function() {
    	console.log(`This vehicle is running on ${this.energyType}.`);
    }
    
    const c = new Car('gas', 80);
    
    c.run();

    Change to:

    Vehicle.call(this, energyType, energy);
    

    function Vehicle(energyType, energy) {
    	this.energyType = energyType;
    	this.energy = energy;
    }
    
    function Car(energyType, energy) {
    	Vehicle.call(this, energyType, energy);
    
    	this.doors = 4;
    }
    
    Car.prototype = Object.create(Vehicle.prototype);
    
    Vehicle.prototype.run = function() {
    	console.log(`This vehicle is running on ${this.energyType}.`);
    }
    
    const c = new Car('gas', 80);
    
    c.run();