javascript重要的设计模式有三种
一.单例模式
二.组合模式
三.观察者模式
一单例模式
单例模式:不管实例化多少次对象都只占用一个对象的内存空间,为了不产生全局变量污染,需要通过闭包的形式调用相关的函数操作。
核心代码
let GQ = (//一个命名空间
function () {
function CreateObj(name, age) { //一个构造函数
this.name = name;
this.age = age;
}
CreateObj.prototype.fn1 = function () {
console.log(this.name, this.age);
}
let res = null;
return function (name, age) {//闭包的固定格式返回一个函数
if (!res) {
res = new CreateObj();//实例化唯一的一个对象
}
CreateObj.call(res, name, age)//利用call传参数
return res;
}
}
)();
let gq1 = GQ('gq', 20);
gq1.fn1();
let gq2 = GQ('sy', 20);
gq2.fn1();
console.log(gq1 == gq2);//证明只有一个对象的内存空间
二组合模式
通常用于对象属于树状结构的编程,把底层的对象的函数放到上层的对象中去,通过上层的对象统一进行操作,用数组将底层的对象包含进去,再通过循环遍历,逐一执行函数。
function Composite(name) {
this.name = name;
this.type = 'Composite'
this.children = [];
}
Composite.prototype = {
constructor: Composite,
addChild: function (child) {
this.children.push(child);
return this
},
getChild: function (name) {
let elemnets = [];
let pushLeaf = function (item) {
if (item.type === 'Composite') {
item.children.forEach((item) => {
arguments.callee(item)
})
} else if (item.type === 'Leaf') {
elemnets.push(item);
}
}
if (name && this.name !== name) {
this.children.forEach(function (item) {
if (item.name === name && item.type === 'Composite') {
pushLeaf(item)
}
if (item.name !== name && item.type === 'Composite') {
item.children.forEach((item) => {
console.log(item)
arguments.callee(item)
})
}
if (item.name == name && item.type === 'Leaf') {
elemnets.push(item);
}
})
} else {
this.children.forEach((item) => {
pushLeaf(item)
})
}
return elemnets;
},
hardWorking: function (name) {
let leafObject = this.getChild(name);
console.log(leafObject)
for (let i = 0; i < leafObject.length; i++) {
leafObject[i].hardWorking();
}
},
sleeping: function (name) {
}
}
function Leaf(name) {
this.name = name;
this.type = 'Leaf'
}
Leaf.prototype = {
constructor: Leaf,
addChild: function (child) {
throw new Error('不能用')
},
getChild: function (name) {
if (this.name == name) {
return this
}
return null
},
hardWorking: function () {
console.log(this.name + '努力工作')
},
sleeping: function () {
console.log(this.name + '快去睡觉')
}
}
var p1 = new Leaf('张1');
var p2 = new Leaf('张2');
var p3 = new Leaf('张3');
var p4 = new Leaf('张4');
var p5 = new Leaf('张5');
var p6 = new Leaf('张6');
var p7 = new Leaf('张7');
var p8 = new Leaf('张8');
var p9 = new Leaf('张9');
var p10 = new Leaf('张10');
var p11 = new Leaf('张11');
var p12 = new Leaf('张12');
var dept1 = new Composite('北京开发部门');
dept1.addChild(p1).addChild(p2).addChild(p3);
var dept2 = new Composite('北京销售部门');
dept2.addChild(p4).addChild(p5).addChild(p6);
var dept3 = new Composite('长沙开发部门');
dept3.addChild(p7).addChild(p8).addChild(p9);
var dept4 = new Composite('长沙销售部门');
dept4.addChild(p10).addChild(p11).addChild(p12);
var org1 = new Composite('北京分公司');
org1.addChild(dept1).addChild(dept2);
var org2 = new Composite('长沙分公司');
org2.addChild(dept3).addChild(dept4);
var org = new Composite('总部');
org.addChild(org1).addChild(org2);
org.hardWorking('张2');
三观察者模式
通常用于数据的双向绑定
class Observer {
constructor(){
this.obj = {}
}
on(type,fn){//向消息盒子type里添加fn事件
if(!this.obj[type]){
this.obj[type] = [fn]
return this
}else{
this.obj[type].push(fn)
return this
}
}
emit(type,...val){//执行type盒子里的...val函数
let arr = [...val]
if(!this.obj[type]){
return
}else{
for(let i=0;i<this.obj[type].length;i++){
for(let j=0;j<arr.length;j++){
if(arr[j] === this.obj[type][i]){
arr[i]()
}
}
}
}
}
off(type,fn){//删除消息盒子里的fn函数
if(!this.obj[type]){
return
}else{
for(let i=0;i<this.obj[type].length;i++){
if(this.obj[type][i] === fn){
this.obj[type].splice(i,1)
i--
}
}
}
}
}
let obs1 =new Observer();
obs1.on('call',you).on('call',me).on('call',he)
obs1.on('play',lan).on('play',zu).on('play',ping)
obs1.off('call',he)
obs1.emit('call',you,me,he)
obs1.emit('play',lan,zu,ping)
function you(){
console.log('you')
}
function me(){
console.log('me')
}
function he(){
console.log('he')
}
function lan(){
console.log('lan')
}
function zu(){
console.log('zu')
}
function ping(){
console.log('ping')
}