将new操作单独封装,遇到new时,就要考虑是否该用工厂模式
示例
你去购买汉堡,直接点餐,取餐,没必要自己亲手做(这就是一个初始化实例的封装)
商店要‘封装’做汉堡的工作,做好直接给买者

class Product {
constructor(name) {
this.name = name;
}
init() {
alert('init');
}
fn1() {
alert('fn1');
}
fn2() {
alert('fn2');
}
}
class Creator{
create(name){
return new Product(name);
}
}
// 测试
let creator = new Creator();
let p = creator.create('p1');
p.init();
p.fn1();
这个Creator就是个工厂,里面有create函数,工厂通过create函数创建product。这样通过create已经把真正的构造函数封装起来,外部只需要知道create能生成一个 实例就行
其他场景
jquery-$('div')
$('div')和new $('div')。会发现前面的工厂使用方便,如果每次都要加个new会比较麻烦。jQuery的链式操作将称为噩梦。一旦jquey名字变化,将是灾难性的。
class jQuery{
constructor(selector){
let slice = Array.prototype.slice;
// 返回一个数组,将arguments对象的数组提出来转化为数组,arguments本身并不是数组而是对象
let dom = slice.call(document.querySelectorAll(selector));
let len = dom ? dom.length : 0;
for(let i = 0; i < len; i++) {
this[i] = dom[i];
}
this.length = len;
this.selector = selector || ''
}
append(node){
}
addClass(name){
}
html(data) {
}
// 此处省略n个API
}
window.$ = function(selector) {
return new jQuery(selector);
}
$p = $('p');
console.log($p);
console.log($p.addClass);
return new jQuery(selector)。这个就是工厂模式,不开放出去。
React.createElement
var profile = `
<div>
<img src='avatar.png' className='profile' />
<h3>{[user.firstName, user.lastName].join(' ')}</h3>
</div>
`
var profile = React.createElement('div', null,
React.createElement('img', {src:'avatar.png', className:'profile'}),
React.createElement('h3', null, [user.firstName, user.lastName].join(' '))
)
React.createElement就是一个工厂模式,后面实例我们不知道。被封装好了,想知道是什么,除非看源码
class Vnode {
constructor(tag, attrs, children){
// ...
}
// ...
}
React.createElement = function (tag, attrs, children) {
return new Vnode(tag, attrs, children)
}
如果不是通过createElement,把new Vnode直接给用户,这样用户会比较麻烦
设计原则验证
1、构造函数和创建者分离
2、符合开放封闭原则