嘿伙计我是javascript的新手,我被建议阅读这本书learning javascript design patterns,我正在阅读工厂设计模式并遇到以下困难,请看下面的脚本:
// Types.js - Constructors used behind the scenes
// A constructor for defining new cars
function Car( options ) {
// some defaults
this.doors = options.doors || 4;
this.state = options.state || "brand new";
this.color = options.color || "silver";
}
// A constructor for defining new trucks
function Truck( options){
this.state = options.state || "used";
this.wheelSize = options.wheelSize || "large";
this.color = options.color || "blue";
}
// FactoryExample.js
// Define a skeleton vehicle factory
function VehicleFactory() {}
// Define the prototypes and utilities for this factory
// Our default vehicleClass is Car
VehicleFactory.prototype.vehicleClass = Car;
// Our Factory method for creating new Vehicle instances
VehicleFactory.prototype.createVehicle = function ( options ) {
switch(options.vehicleType){
case "car":
this.vehicleClass = Car;
break;
case "truck":
this.vehicleClass = Truck;
break;
//defaults to VehicleFactory.prototype.vehicleClass (Car)
}
return new this.vehicleClass( options );
};
// Create an instance of our factory that makes cars
var carFactory = new VehicleFactory();
var car = carFactory.createVehicle( {
vehicleType: "car",
color: "yellow",
doors: 6 });
// Test to confirm our car was created using the vehicleClass/prototype Car
// Outputs: true
console.log( car instanceof Car );
// Outputs: Car object of color "yellow", doors: 6 in a "brand new" state
console.log( car );
这是我为工厂设计模式找到的例子,现在我的问题是理解以下一行:
考虑到vehicleClass类被定义为变量:
VehicleFactory.prototype.vehicleClass = Car;
我不明白它是作为构造函数返回的:
return new this.vehicleClass( options );
好吧,这是我唯一的困难,一次又一次地运行代码,对我来说仍然没有意义。
如果有人能向我解释,我将不胜感激。
谢谢。
亚历山大答案 0 :(得分:1)
您分配给VehicleFactory.prototype.vehicleClass
的内容不是实际class
,而是对constructor function
的引用。
要在JavaScript中创建对象,new运算符必须后跟构造函数。由于代码VehicleFactory.prototype.vehicleClass
中的this.vehicleClass
或更高版本包含对构造函数的引用,因此您可以使用new this.vehicleClass(options)
创建新的车辆对象。
JavaScript的一大优势是能够将函数作为参数传递,而无需代理。
我希望这会让它更清晰一点。
问候
答案 1 :(得分:1)
这里返回的不是一个函数(你是对的,它没有意义)。返回的是一个新对象(请参阅new
关键字)。
如果要返回类型为Truck
的新对象,请使用代码:
return new Truck( options )
然而,在这种特定情况下,您想要的车辆类型由用户定义。所以this.vehicleClass
指的是返回上方的开关中定义的值。换句话说,如果用户选择vehicleClass
(分别为Car
),则Truck
将替换为car
(分别为Truck
)。
因此,将被调用的构造函数将是代码第一行中定义的Car
或Truck
构造函数。
我希望现在更清楚了。
答案 2 :(得分:1)
在Javascript中函数是对象,因此可以将它们用作返回值。这意味着函数不需要因执行而返回某种数据值或数据数组。
函数可以返回另一个更专业的函数,或者它可以按需创建另一个函数,具体取决于某些输入。 这是一个简单的例子:一个函数做一些工作,可能是一些一次性初始化,然后处理它的返回值。返回的值恰好是另一个函数,也可以执行:
var setup = function () {
alert(1);
return function () {
alert(2);
};
};
// using the setup function
var my = setup(); // alerts 1
my(); // alerts 2
因为 setup()包装了返回的函数,所以它创建了一个闭包,你可以使用这个闭包来存储一些私有数据,这些数据可以由返回的函数访问,但不能访问外部代码。一个例子是一个计数器,每次调用它时都会给你一个递增的值:
var setup = function () {
var count = 0;
return function () {
return (count += 1);
};
};
// usage
var next = setup();
next(); // returns 1
来源:JavaScript Patterns按Stoyan Stefanov。
在您的情况return new this.vehicleClass( options );
中,返回一个新对象调用构造函数vehicleClass
。
答案 3 :(得分:1)
new <expression>(<arguments>)
的评估如下:
<expression>
new <result of 1>(<arguments>)
也就是说,只要此表达式返回一个函数,就可以在new
和左括号之间放置任何表达式。
VehicleFactory.prototype.vehicleClass = Car;
然后,在createVehicle
中,它添加了一个具有相同名称的本地属性:
this.vehicleClass = Car;
在后续查找中有效覆盖prototype
的{{1}}:
vehicleClass
设计 a = createVehicle(); // no `vehicleType` here, returns `Car`
b = createVehicle({vehicleType: 'truck'}); // returns `Truck`
c = createVehicle(); // no `vehicleType` here, but this time it returns `Truck`???
的更好方法是这样的:
createVehicle
在主观上,“设计模式”在javascript中并不是非常惯用,如果你想要另一个阅读建议,请试试JavaScript Allongé。