Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/440.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/tensorflow/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
属性访问器可以有Javascript中的原型吗_Javascript - Fatal编程技术网

属性访问器可以有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