前端设计模式
12 Dec 2018工厂模式
//类模板
class Mobile {
constructor(name){
this.name = name;
}
call(){
console.log(this.name + ' call');
}
}
//工厂
class CreaterFactory {
create(name){
return new Mobile(name);
}
}
var factory = new CreaterFactory();
var iphone = factory.create('iphone');
iphone.call();
单例模式
class Person{
constructor(){
}
say(){
console.log('say...');
}
}
Person.getInstance = (function(){
let instance;
return function(){
if(!instance){
instance = new Person()
}
return instance;
}
})();
var p1 = Person.getInstance();
p1.say();
var p2 = Person.getInstance();
p2.say();
console.log(p1 === p2);
适配器(装饰器)模式
示例1
class Adapter{
constructor(){}
outStandard(){
return '国外电压 110v'
}
}
class TargetAdapter{
constructor(){
this.adapter = new Adapter();
}
standard(){
let outstandard = this.adapter.outStandard();
return `${outstandard} => 国内电压 220v`;
}
}
var target = new TargetAdapter();
console.log(target.standard());
示例2
class Circle{
draw(){
console.log('draw circle');
}
}
class CircleDecorator{
constructor(circle){
this.circle = circle;
}
draw(){
this.circle.draw();
this.setColor();
}
setColor(){
console.log('set circle color');
}
}
var circle = new Circle();
circle.draw();
console.log('-------------------');
var decorator = new CircleDecorator(circle);
console.log(decorator);
decorator.draw();
es7装饰器示例(需配置 babel plugins: babel-plugin-transform-decorators-legacy)
.babelrc
{
"plugins": ["transform-decorators-legacy"]
}
//es7 Decorator
import { readonly, deprecate } from 'core-decorators';
// function readonly(target,name,descriptor){
// descriptor.writable = false;
// return descriptor;
// }
class Character {
constructor(name){
this.name = name;
}
@readonly
getname(){
console.log(this.name);
}
@deprecate
facepalm() {}
}
var p = new Character('blue');
p.getname();
p.facepalm();
// p.getname = function(){}
代理模式
示例1
class RealImg{
constructor(filename){
this.filename = filename;
this.loadIn();
}
display(){
console.log('display img ' + this.filename);
}
loadIn(){
console.log('loading... ' + this.filename);
}
}
class ProxyImg{
constructor(filename){
this.filename = new RealImg(filename);
}
display(){
this.filename.display();
}
}
var prox = new ProxyImg('example.png');
prox.display();
es6 proxy 示例
let star = {
name: 'blue',
age: 23,
phone: 'star: 186xxxxxxxx'
}
let agent = new Proxy(star,{
get(target, key){
if(key == 'phone'){
return 'agent: 138xxxxxxxx'
}
return target[key];
},
set(target, key, val){
if(key === 'price'){
if(val < 100000){
throw new Error('price is to low');
}
}
target[key] = val;
return true;
}
});
console.log(agent.name);
console.log(agent.phone);
console.log(agent.price);
agent.price = 140000;
console.log(agent.price);
观察者模式
示例:
class Substribe{
constructor(){
this.state = 0;
this.observers = [];
}
getState(){
return this.state;
}
setState(state){
this.state = state;
this.noticifyAll();
}
noticifyAll(){
this.observers.forEach(obs => {
obs.update()
})
}
attach(obs){
this.observers.push(obs);
}
}
class Observer{
constructor(name,substribe){
this.name = name;
this.substribe = substribe;
this.substribe.attach(this);
}
update(){
console.log(`${this.name} update state ${this.substribe.getState()}`);
}
}
var s = new Substribe();
var o1 = new Observer('o1',s);
var o2 = new Observer('o2',s);
s.setState(1);
自定义事件
class MyEvent{
constructor(){
this.events = {};
}
on(type,fn){
if(!this.events[type]){
this.events[type] = [];
}
this.events[type].push(fn);
}
emit(type){
this.events[type].forEach(fn => {
fn();
});
}
}
var myevent = new MyEvent();
myevent.on('aa',function(){
console.log('aa');
});
myevent.on('bb',function(){
console.log('bb');
});
myevent.on('aa',function(){
console.log('from aa');
});
myevent.emit('aa');
myevent.emit('bb');
迭代器模式(顺序访问一个有序集合)
示例
class Iterator {
constructor(container){
this.list = container.list;
this.index = 0;
}
next(){
if(this.hasNext()){
return this.list[this.index++];
}
return null;
}
hasNext(){
if(this.index >= this.list.length){
return false
}
return true;
}
}
class Container{
constructor(list){
this.list = list;
}
getIterator(){
return new Iterator(this);
}
}
var container = new Container([1,2,3]);
var iterator = container.getIterator()
while(iterator.hasNext()){
console.log(iterator.next());
}
示例 es6 Iterator(简化版 使用 for … of )
function each(data){
let iterator = data[Symbol.iterator]();
let item = {done: false}
while(!item.done){
item = iterator.next();
if(!item.done){
console.log(item.value);
}
}
}
each(new Set([1,2,3]));
状态模式
class TrafficLight{
constructor(){
this.state = null
}
getState(){
return this.state;
}
setState(state){
this.state = state;
}
}
class LightState {
constructor(color){
this.color = color;
}
handler(context){
console.log(`turn to ${this.color} light`);
context.setState(this);
}
}
var trafficligt = new TrafficLight();
var red = new LightState('red');
red.handler(trafficligt);
console.log(trafficligt.getState());
var green = new LightState('green');
green.handler(trafficligt);
console.log(trafficligt.getState());
var yellow = new LightState('yellow');
yellow.handler(trafficligt);
console.log(trafficligt.getState());
Promise 简单实现
function Promise(fn){
var that = this;
this.state = 'pendding';
this.value = '';
this.resolveCallbacks = [];
this.rejectCallbacks = [];
this.then = function(onResolve, onReject){
if(this.state == 'pending'){
this.resolveCallbacks.push(onResolve);
this.rejectCallbacks.push(onReject);
}
if(this.state == 'resolve'){
onResolve(this.value);
}
if(this.state == 'reject'){
onReject(this.value);
}
}
function resolve(value){
if(this.state === 'pending'){
this.state === 'reslove';
this.value = value;
setTimeout(function(){
that.resolveCallbacks.forEach(fn=>fn(that.value))
},0);
}
}
function reject(value){
if(this.state === 'pending'){
this.state === 'reject';
this.value = value;
setTimeout(function(){
that.rejectCallbacks.forEach(fn=>fn(that.value))
},0);
}
}
try{
fn(resolve,reject);
}catch(e){
reject(e);
}
}
队列实现
var a = function(data){
return new Promise(function(resolve,reject){
setTimeout(function(){
console.log('a',data);
resolve('a');
},1000);
});
}
var b = function(data){
return new Promise(function(resolve,reject){
setTimeout(function(){
console.log('b',data);
resolve('b');
},1000);
});
}
var c = function(data){
return new Promise(function(resolve,reject){
setTimeout(function(){
console.log('c',data);
resolve('c');
},1000);
});
}
var arr = [a,b,c]
function Queue(arr){
var sequeue = Promise.resolve();
arr.forEach(function(item){
sequeue = sequeue.then(item);
});
return sequeue;
}
Queue(arr).then(data=>{
console.log(data);
});
深拷贝
function deepCopy(obj){
let temp = obj instanceof Array ? []: {};
for(var key in obj){
temp[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key];
}
return temp;
}
函数防抖
function debounce(fn,wait){
var timeout = null;
return function(){
clearTimeout(timeout);
timeout = setTimeout(function(){
fn.apply(this,arguments);
},wait);
}
}
函数节流
function throttle(fn,interval){
let canRun = true;
interval = interval ? interval : 3000;
return function(){
if(!canRun) return;
canRun = false;
setTimeout(function(){
fn.apply(this,arguments);
canRun = true;
},interval);
}
}
call apply 实现
Function.prototype.call = function(context){
if(typeof this !== 'function'){
throw Error();
}
context = context || window;
context.fn = this;
var arg = arguments.splice(1);
var result = context.fn(..arg);
delete context.fn;
return result;
}