How do you create an instance of an instance in JavaScript

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;
        }
    }
    

    If you want the Car instances to be constructors, Car must return a constructor.

    The problem is that then it will inherit from Function.prototype instead of Car.prototype . If that's undesirable, use Object.setProtetypeOf to fix it:

    function Person() {
      this.cars = {};
    }
    function Car(make, country) {
      var instance = function(currentPrice, miles) {
        this.currentPrice = currentPrice;
        this.miles = miles;
      };
      instance.make = make;
      instance.country = country;
      Object.setPrototypeOf(instance, Car.prototype); // slow!!
      return instance;
    }
    var Ferrari = new Car('Ferrari', 'Italy');
    var fred = new Person();
    fred.cars.ferrari = new Ferrari(1200, 300000);
    

    Alternatively, you can add a method which will be used to "instantiate" your instances.

    function Person() {
      this.cars = {};
    }
    function Car(make, country) {
      this.make = make;
      this.country = country;
    }
    Car.prototype.instantiate = function(currentPrice, miles) {
      var instance = Object.create(this);
      instance.currentPrice = currentPrice;
      instance.miles = miles;
      return instance;
    };
    var ferrari = new Car('Ferrari', 'Italy');
    var fred = new Person();
    fred.cars.ferrari = ferrari.instantiate(1200, 300000);
    
    链接地址: http://www.djcxy.com/p/91424.html

    上一篇: 如何使按钮点击一次选框循环一次?

    下一篇: 你如何在JavaScript中创建一个实例的实例