I want to make unique instances of a set of cars that different people can hold. The cars will have similar base specs but some of their properties and methods will vary.
The problem I have is that I can't work out how this should work. How do you deal with or create instances of instances in JavaScript?
var Car = function(make, country) {
this.make = make;
this.country = country;
};
var Ferrari = new Car('Ferrari', 'Italy');
var fred = new Person() {};
var fred.cars['Ferrari'] = new Ferrari(1200, 300000);
This causes this error, for obvious reasons. I am aware it is not a constructor (see below).
Uncaught TypeError: Ferrari is not a constructor
What I am looking for is something like this. Each different instance of a Ferrari will have a different price and milage.
var Ferrari = function(currentPrice, miles) }
this.currentPrice = currentPrice;
this.miles = miles;
// this is an instance of car, aka it needs the result of this:
// new Car('Ferrari', 'Italy');
};
Fred's Ferrari is an instance of Ferrari, which is an instance of Car. The problem is that I can't think of a way to make a constructor build a constructor. Is there a way to do this, or am I just going about this in the wrong way?
Other Notes:
I know I could essentially just make each type of car a static JSON-like object and then make instances of that and add new unique values. However, I would like to be able to keep the Car as a constructor so I can easily make more when I need to.
I am clearly missing some understanding of OOP or JavaScript here, but it would be great if someone could point me in the right direction.
What you're looking for is a derived constructor and associated prototype, sometimes called a subclass.
In old-fashioned ES5 it looks like this:
var Car = function(make, country) {
this.make = make;
this.country = country;
};
var Ferrari = function(currentPrice, miles) {
Car.call(this, "Ferrari", "Italy");
this.currentPrice = currentPrice;
this.miles = miles;
};
Ferrari.prototype = Object.create(Car.prototype);
Ferrari.prototype.constructor = Ferrari;
How that works:
Ferrari
is a constructor function that, when called, calls Car
with this
referring to the new instance, along with the arguments Car
needs. Car
does its thing setting up those properties on the instance. Then we continue with Ferrari
's code, which takes the arguments passed in and (in the above) remembers them as properties.
We ensure that the object that will be assigned to instances by new Ferrari
(which is taken from Ferrari.prototype
) uses Car.prototype
as its prototype object, so that if you add things to Car.prototype
, they'll be present on Ferrari
s as well.
We ensure that the standard constructor
property on Ferrari.prototype
refers to Ferrari
.
Rather nicer in ES2015 (which you can use today via transpilation, such as with tools like Babel):
class Car {
constructor(make, country) {
this.make = make;
this.country = country;
}
}
class Ferrari extends Car {
constructor(currentPrice, miles) {
super("Ferrari", "Italy");
this.currentPrice = currentPrice;
this.miles = miles;
}
}