如何在JavaScript中创建实例的实例
我想为不同的人可以持有的一组汽车制作独特的实例。这些汽车将有类似的基本规格,但它们的一些属性和方法将有所不同 我的问题是我不知道该怎么做。如何在JavaScript中处理或创建实例的实例如何在JavaScript中创建实例的实例,javascript,oop,constructor,instances,Javascript,Oop,Constructor,Instances,我想为不同的人可以持有的一组汽车制作独特的实例。这些汽车将有类似的基本规格,但它们的一些属性和方法将有所不同 我的问题是我不知道该怎么做。如何在JavaScript中处理或创建实例的实例 var Car=功能(品牌、国家){ make=make; 这个国家=国家; }; var Ferrari=新车(“法拉利”、“意大利”); var fred=newperson(){}; var fred.cars['Ferrari']=新法拉利(1200,300000); 这导致了这个错误,原因很明显。我
var Car=功能(品牌、国家){
make=make;
这个国家=国家;
};
var Ferrari=新车(“法拉利”、“意大利”);
var fred=newperson(){};
var fred.cars['Ferrari']=新法拉利(1200,300000);
这导致了这个错误,原因很明显。我知道它不是一个构造函数(见下文)
未捕获类型错误:法拉利不是构造函数
我要找的是这样的东西。法拉利的每一个不同实例都有不同的价格和相似性
var ferari=函数(当前价格,英里)}
this.currentPrice=currentPrice;
这个。英里=英里;
//这是car的一个实例,也就是它需要以下结果:
//新车(“法拉利”、“意大利”);
};
弗雷德的法拉利是法拉利的一个例子,法拉利是汽车的一个例子。问题是,我想不出一种方法让一个构造函数构建一个构造函数。是有办法做到这一点,还是我只是走错了路
其他注意事项:
我知道我基本上可以让每种类型的汽车都成为一个类似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
,其中Car
引用新实例,以及this
所需的参数Car
在实例上设置这些属性。然后我们继续使用法拉利的代码,它接受传入的参数,并(在上面)将它们作为属性记住Car
- 我们确保
将分配给实例的对象(取自new Ferrari
)使用Ferrari.prototype
作为其原型对象,因此如果您向Car.prototype
添加内容,它们也将出现在Car.prototype
上Ferrari
- 我们确保
上的标准Ferrari.prototype
属性是指constructor
Ferrari
如果希望
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);
Ferrari
应该是一个子类,而不是一个实例;它应该扩展Car
。对于像我这样困惑的人来说,MDN上有一个很好的页面,它解释了与基于类的语言相比如何在JS中创建对象层次结构:@Jordão:谢谢!ES2015示例看起来与我在PHP中看到的类似,但在Javascript中找不到类似的功能。谢谢还值得一提的是,OP的类模型被打破了,price
和miles
属性实际上属于基本属性class@jamcd:它相对较新,由2015年6月的规范引入,这就是为什么如果您想在野外使用它,就需要Transbile(如果你想在当前的Chrome或NodeJS上使用它,你不知道)。是的,它有意地与其他语言(比如Java)中的类似构造相似。@jamcd每辆车都有价格(即使你不知道它是什么)谢谢你提供了一个替代方法。如果你不介意我问的话,使用这个方法而不是“调用”方法有什么好处吗?@jamcd它们是不同的方法。call
在子类化时使用,以便从扩展的构造函数调用超级构造函数。但是你想实例化实例,而不是子构造函数。因此构造函数已经被调用来创建您想要实例化的实例,然后就没有理由再调用它了。我提供的方法相对于子类化的优点是,您不需要事先知道汽车名称(例如法拉利)。从这个问题上,我明白这是您想要的,而不是子类化。
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);