如何在JavaScript中创建实例的实例

How do you create an instance of an instance in JavaScript

本文关键字:实例 创建 JavaScript      更新时间:2023-09-26

我想为一组不同的人可以持有的汽车创建独特的实例。这些汽车的基本规格相似,但它们的一些特性和方法会有所不同。

我的问题是我不知道该怎么做。如何在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);

这导致了这个错误,原因很明显。我知道它不是构造函数(见下文)。

Uncaught TypeError: Ferrari is not a constructor

我要找的是这样的东西。法拉利的每一个不同实例都有不同的价格和相似性。

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

弗雷德的法拉利是法拉利的一个例子,这是汽车的一个实例。问题是,我想不出让构造函数构建构造函数的方法。有没有办法做到这一点,或者我只是以错误的方式去做这件事?

其他注意事项:

我知道我基本上可以让每种类型的汽车都成为一个类似JSON的静态对象,然后创建它的实例并添加新的唯一值。然而,我希望能够保留汽车作为一个建设者,这样我就可以在需要的时候轻松地制造更多。

我在这里显然缺少对OOP或JavaScript的一些理解,但如果有人能为我指明正确的方向,那就太好了。

您正在寻找的是一个派生构造函数和相关原型,有时称为子类

在老式的ES5中,它看起来像这样:

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;

工作原理:

  • Ferrari是一个构造函数,当被调用时,它调用Carthis引用新实例,以及Car需要的参数。Car在实例上设置这些属性。然后,我们继续使用Ferrari的代码,它接受传入的参数,并(在上面)将它们作为属性进行记忆。

  • 我们确保将由new Ferrari(取自Ferrari.prototype)分配给实例的对象使用Car.prototype作为其原型对象,这样,如果您向Car.prototype添加内容,它们也将出现在Ferrari上。

  • 我们确保Ferrari.prototype上的标准constructor属性是指Ferrari

在ES2015中表现得更好(你现在可以通过transpillation使用,比如使用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;
    }
}

如果希望Car实例是构造函数,则Car必须返回一个构造函数。

问题是它将继承自Function.prototype而不是Car.prototype。如果不需要,请使用Object.setProtetypeOf进行修复:

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

或者,您可以添加一个用于"实例化"实例的方法。

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