工厂方法
工厂方法是一个简化地返回对象的函数。它不需要像构造器那样用 new 关键字来初始化对象。
通常,工厂方法作为API封装,就像 jQuery 和 moment.js 中那样,不使用 new 。
下面是最简单的工厂方法:
function cowFactory(name) {
return {
name: name,
talk: function () {
console.log('Moo, my name is ' + name);
},
};
}
var daisy = cowFactory('Daisy'); // create a cow named Daisy
daisy.talk(); // "Moo, my name is Daisy"
很容易就可以在工厂中定义private的属性和方法,只要把它们包含在return之外。
function cowFactory(name) {
function formalName() {
return name + ' the cow';
}
return {
name: name,
talk: function () {
console.log('Moo, my name is ' + formalName());
},
};
}
var daisy = cowFactory('Daisy');
daisy.talk(); // "Moo, my name is Daisy the cow"
daisy.formalName(); // ERROR: daisy.formalName is not a function
工厂是在JavaScript中是一种实践函数式编程的绝佳方式,因为它们是函数。
组合式工厂
“用组合而不是继承”是一个重要的编程理念,用于给对象指定行为,而不用继承很多不需要的行为。
- 行为工厂
var speaker = function (state) {
var noise = state.noise || 'grunt';
return {
speak: function () {
console.log(state.name + ' says ' + noise);
}
};
};
var mover = function (state) {
return {
moveSlowly: function () {
console.log(state.name + ' is moving slowly');
},
moveQuickly: function () {
console.log(state.name + ' is moving quickly');
}
};
};
- 对象工厂
var person = function (name, age) {
var state = {
name: name,
age: age,
noise: 'Hello'
};
return Object.assign( // Merge our 'behaviour' objects
{},
speaker(state),
mover(state)
);
};
var rabbit = function (name, colour) {
var state = {
name: name,
colour: colour
};
return Object.assign(
{},
mover(state)
);
};
使用方式:
var fred = person('Fred', 42);
fred.speak(); // outputs: Fred says Hello
fred.moveSlowly(); // outputs: Fred is moving slowly
var snowy = rabbit('Snowy', 'white');
snowy.moveSlowly(); // outputs: Snowy is moving slowly
snowy.moveQuickly(); // outputs: Snowy is moving quickly
snowy.speak(); // ERROR: snowy.speak is not a function