属性访问器可以有Javascript中的原型吗
我的问题如下代码示例:属性访问器可以有Javascript中的原型吗,javascript,Javascript,我的问题如下代码示例: // 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 CarFact
// 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();
本例中的轿车是一种财产。但到目前为止,我看到的大多数示例都将新属性或函数直接附加到主对象上。例如:
CarFactory.prototype.manufacturer=新制造商()
那么,prototype属性用于向现有属性或函数添加新属性或函数是真的吗?
CarFactory.Sedan
、CarFactory.Compact
、和CarFactory.SUV
都是构造函数(比如CarFactory
本身就是构造函数)。因此,它们有一个名为prototype
的属性,该属性指的是将用作通过new CarFactory.Sedan
等创建的对象原型的对象
这些功能(Sedan
、Compact
、SUV
)也通过CarFactory
上的属性引用,这与它们是构造函数这一事实没有区别
那么,prototype属性用于向现有属性或函数添加新属性或函数,这是真的吗
的确,构造函数函数的prototype
属性指的是将用作通过该函数创建的对象原型的对象。因此,添加到该对象会添加通过原型继承对这些对象可用的特性
但是,该代码有几个问题,特别是在
make
功能中:
make
时,重新创建一个新的CarFactory
对象并将其分配给CarFactory[constr].prototype
没有任何意义。它正在为make
创建的每个对象创建一个新的原型,这是毫无意义的。原型的主要目的是重用new Xyz
创建一个对象以放置在另一个构造函数的prototype
属性上通常是反模式的一部分。(在这种情况下,它是无害的,CarFactory
不接受任何参数;在一般情况下,这是不好的做法。)轿车
等),而不是部分设置它们,然后重新使用它们。以下是我要做的最小改动:
var CarFactory=(函数(){
//工厂建造师
函数CarFactory(){
}
//原型方法
CarFactory.prototype.info=函数(){
console.log(“这辆车有“+This.doors+”车门和一个“+This.engine_容量+”升发动机”);
};
//静态工厂法
CarFactory.make=功能(类型){
var ctor=汽车工厂[类型];
if(!ctor){
抛出新错误(“未知类型“'+类型+””);
}
返回新的ctor();
};
//创建汽车类型的函数
函数makeCarType(ctor){
ctor.prototype=Object.create(CarFactory.prototype);
ctor.prototype.constructor=ctor;
回归系数;
}
//类型
CarFactory.Compact=makeCarType(函数(){
该值为4;
该发动机容量=2;
});
CarFactory.Sedan=makeCarType(函数(){
这1.2=2;
该发动机容量=2;
});
CarFactory.SUV=makeCarType(函数(){
该值为4;
该发动机容量=6;
});
返回工厂;
})();
var golf=汽车工厂制造('Compact');
var vento=汽车工厂制造(“轿车”);
var touareg=汽车工厂制造('SUV');
golf.info()//“这辆车有4个门和2升发动机”
vento.info()//“这辆车有两个门和一个2升发动机”
touareg.info()//“这辆车有4门和6升发动机”
在每次调用make
时都给原型分配一个新的汽车工厂()
。这绝对是一个可怕的想法。我从《掌握Javascript》一书中复制了这段代码。关于第1点:是的,我也这么想。似乎有点无意义。但是这个例子是为了演示工厂模式,所以在设置原型时使用新的CarFactory似乎是正确的。没有它,Sedan对象与CarFactory对象就没有真正的连接。因此,即使每次使用make重新创建CarFactory,它也能保证每种车型都有自己的实例。我认为这就是正在实现的目标。但我真正的问题是汽车工厂[constr].prototype=new CarFactory();正在属性上使用。实际上,您通过指出它实际上是指每种汽车类型的构造函数来回答这个问题。所以在现实中,即使这是一个属性访问器,属性访问器实际上是在引用一个构造函数。换句话说,原型不能用于属性。它们只能用于函数或构造函数。在保持工厂模式的同时,您的代码示例看起来确实更好。谢谢你的洞察力@AndroidDev:只是FWIW,我……不相信……将该代码作为工厂模式的示例。:-)关于你的第二条评论:你必须小心你的术语:构造函数的prototype
属性不是“prototype”,它只是一个引用对象的属性。如果将new
与该构造函数一起使用,则该对象将成为所创建的新对象的原型。但是是的,CarFactory[const]
检索对构造函数的引用,因此使用其prototype
属性就是使用构造函数的prototype
属性。作为一个不相关的问题,每种车型都有两个pro