一、设计模式
在面向对象开发过程中,针对频繁出现的问题,总结出来的最优的解决方案
单例模式 让一个类只能有一个实例对象
优点:
划分命名空间,减少全局变量
增强模块性,把自己的代码组织在一个全局变量名下,放在单一位置,便于维护
且只会实例化一次。简化了代码的调试和维护
缺点:
由于单例模式提供的是一种单点访问,所以它有可能导致模块间的强耦合 从而不利于单元测试。无法单独测试一个调用了来自单例的方法的类,而只能把它与那个单例作为一个单元一起测试。
// 自调用
var f= (function dan() {
class Person { }
var p
return function () {
if (!p) {
p = new Person()
} return p
}
})()
var p1 = f()
var p2 = f()
console.log(p1==p2);
组合模式 批量的启动器
class start{
container=[]
add(...arr){
this.container=this.container.concat(arr)
}
qidong(){
this.container.forEach(jsonobj => {
console.log(jsonobj);
for(var key in jsonobj){
jsonobj[key][key]()
}
});
}
}
var xin = new start
xin.add({bobo:new Tab('.tab')},{startl:new Lunbo('.carousel')})
// xin.add({popo:new Enlarge('.enlarge'))
xin.qidong()
发布订阅者模式
发布者负责发布消息,订阅者负责订阅消息,订阅者接收到发布者发布的消息是自己订阅的消息后,就执行一段代码。
class fubu{
container=[]
add(...arr){
this.container=this.container.concat(arr)
}
fb(ems){
this.container.forEach(dingyuezhe=>{
if(dingyuezhe.essmge===ems){
dingyuezhe.hander()
}
})
}
}
class dingyi {
constructor({essmge,hander}){
this.essmge=essmge
this.hander=hander
}
}
var xiaoming =new dingyi({
essmge:'买烟',
hander:function(){
console.log('可以买盐了');
}
})
var xiaojing =new dingyi({
essmge:'买牛奶',
hander:function(){
console.log('可以买牛奶了');
}
})
var f = new fubu()
f.add(xiaoming,xiaojing)
f.fb('买烟')
f.fb('买牛奶')
观察者模式 自己观察自己执行
优点:
支持简单的广播通信,自动通知所有已经订阅过的对象
目标对象与观察者之间的抽象耦合关系能单独扩展以及重用
增加了灵活性
观察者模式所做的工作就是在解耦,让耦合的双方都依赖于抽象,而不是依赖于具体。从而使得各自的变化都不会影响到另一边的变化。
缺点:过度使用会导致对象与对象之间的联系弱化,会导致程序难以跟踪维护和理解
class jian{
constructor(){
this.container ={}
}
// 事件绑定
bang(type,hander){
if(!this.container.hasOwnProperty(type)){
this.container[type]=[]
}
this.container[type].push(hander)
}
// 事件解绑
jiebang(type,hander){
if(!this.container.hasOwnProperty(type)){
alert(type + '事件还没有绑定')
return
}
var index=this.container[type].indexOf(hander)
if(index<0){
alert(type + '事件还没有绑定')
return
}
this.container[type].splice(index, 1)
if(this.container[type].length === 0) {
delete this.container[type]
}
}
// 事件触发
chu(type){
if(!this.container.hasOwnProperty(type)){
alert(type + '事件还没有绑定')
return
}
this.container[type].forEach(fn=>fn())
}
clear(type) {
delete this.container[type]
}
}
var w=new jian()
console.log(w);
// 给w绑定事件
w.bang('a',a1)
function a1(){
console.log('这是a事件的a1函数');
}
w.bang('a',a2)
function a2(){
console.log('这是a事件的a2函数');
}
w.bang('b',b1)
function b1(){
console.log('这是b事件的b1函数');
}
console.log(w);
w.jiebang('a',a1)
console.log(w)
w.chu('a')
w.chu('b')
console.log(w);
二、垃圾回收机制
js的垃圾回收机制叫GC,垃圾回收是动态存储管理技术,会自动地释放“垃圾‘’(不再被程序引用的对象),按照特定的垃圾收集算法 来实现资源自动回收的功能。
回收的两种机制
1.标记清除(make-and-sweep) :先遍历所有空间,将能访问到的数据空间做标记,再次遍历所有空间,将没有做标记的数据空间清除。
缺点:容易造成内存碎片化
2.标记整理法:先将所有能访问到的数据空间放在最前面,将所有访问不到的数据空间放在最后面,然后进行标记清除。
3.引用计数:数据每次被引用一次,就计数一次,当计数为0的时候,清除数据空间
垃圾回收器会按照固定的时间间隔周期性的执行
缺点:两个对象互相引用,就无法清除了,闭包也无法清除