我的问题遵循以下代码示例:
// Factory Constructor
function CarFactory() {
}
CarFactory.prototype.info = function () {
console.log("This car has " + this.doors + " doors and a " + this.engine_capacity + " liter engine");
};
// the static factory method
CarFactory.make = function (type) {
var constr = type;
var car;
CarFactory[constr].prototype = new CarFactory();
// create a new instance
car = new CarFactory[constr]();
return car;
};
CarFactory.Compact = function () {
this.doors = 4;
this.engine_capacity = 2;
};
CarFactory.Sedan = function () {
this.doors = 2;
this.engine_capacity = 2;
};
CarFactory.SUV = function () {
this.doors = 4;
this.engine_capacity = 6;
};
var golf = CarFactory.make('Compact');
var vento = CarFactory.make('Sedan');
var touareg = CarFactory.make('SUV');
golf.info(); //"This car has 4 doors and a 2 liter engine"
我理解如何使用prototype属性为函数添加其他属性。但是,在此代码示例中,我发现特殊的代码行是:
CarFactory[constr].prototype = new CarFactory();
这里,CarFactory [constr]是一个属性访问者。这可能是这样写的:
CarFactory.Sedan.prototype = new CarFactory();
此示例中的Sedan是一个属性。但是到目前为止我见过的大多数示例都是直接在主对象上附加新属性或函数。例如:
CarFactory.prototype.manufacturer = new Manufacturer();
因此,声明prototype属性用于向现有属性或函数添加新属性或函数是真的吗?
答案 0 :(得分:2)
CarFactory.Sedan
,CarFactory.Compact
和CarFactory.SUV
都是构造函数(如CarFactory
本身就是)。所以他们有一个名为prototype
的属性,它引用了将用作通过new CarFactory.Sedan
等创建的对象原型的对象。
这些函数(Sedan
,Compact
,SUV
)也通过CarFactory
上的属性引用的事实对它们是构造函数的事实没有任何影响。
因此,声明prototype属性用于向现有属性或函数添加新属性或函数是真的吗?
确实,构造函数的prototype
属性指的是将用作通过new
使用该函数创建的对象原型的对象。因此,添加到该对象会添加通过原型继承可用于这些对象的功能。
但是,该代码存在一些问题,特别是在make
函数中:
CarFactory
时,重新创建新的CarFactory[constr].prototype
对象并将其分配给make
是没有意义的。它为make
创建的每个对象创建了一个新原型,这是毫无意义的。原型的主要目的是重用。new Xyz
创建一个对象以放置另一个构造函数的prototype
属性通常是反模式的一部分。 (在这种情况下它是无害的,CarFactory
没有采取任何参数;在一般情况下,它的做法很差。)我完全设置了汽车类型(Sedan
等),而不是部分设置它们,然后重复使用它们。以下是最低更改:
var CarFactory = (function() {
// Factory Constructor
function CarFactory() {
}
// Prototype methods
CarFactory.prototype.info = function() {
console.log("This car has " + this.doors + " doors and a " + this.engine_capacity + " liter engine");
};
// The static factory method
CarFactory.make = function(type) {
var ctor = CarFactory[type];
if (!ctor) {
throw new Error("Unknown type '" + type + "'");
}
return new ctor();
};
// Function to create types of cars
function makeCarType(ctor) {
ctor.prototype = Object.create(CarFactory.prototype);
ctor.prototype.constructor = ctor;
return ctor;
}
// Types
CarFactory.Compact = makeCarType(function() {
this.doors = 4;
this.engine_capacity = 2;
});
CarFactory.Sedan = makeCarType(function() {
this.doors = 2;
this.engine_capacity = 2;
});
CarFactory.SUV = makeCarType(function() {
this.doors = 4;
this.engine_capacity = 6;
});
return CarFactory;
})();
var golf = CarFactory.make('Compact');
var vento = CarFactory.make('Sedan');
var touareg = CarFactory.make('SUV');
golf.info(); //"This car has 4 doors and a 2 liter engine"
vento.info(); //"This car has 2 doors and a 2 liter engine"
touareg.info(); //"This car has 4 doors and a 6 liter engine"

更重要的更改可能是使用ES2015 + class
语法并完全取消CarFactory.make
。