1.js模拟java里的Map
function Map(){
var obj = {} ;
this.put = function(key , value){
obj[key] = value ;
}
this.size = function(){
var count = 0 ;
for(var attr in obj){
count++;
}
return count ;
} this.get = function(key){
if(obj[key] || obj[key] === 0 || obj[key] === false){
return obj[key];
} else {
return null;
}
} this.remove = function(key){
if(obj[key] || obj[key] === 0 || obj[key] === false){
delete obj[key];
}
} this.eachMap = function(fn){
for(var attr in obj){
fn(attr, obj[attr]);
}
} } var m = new Map();
m.put('01' , 'abc');
m.put('02' , false) ;
m.put('03' , true);
m.put('04' , new Date()); m.eachMap(function(key , value){
alert(key +" :"+ value);
});
js模拟java里的Map
2.去除数组重复项
var arr = [2,1,2,10,2,3,5,5,1,10,13]; // js对象的特性 : 在js对象中 key 是永远不会重复的 // 1 把数组转成一个js的对象
// 2 把数组中的值,变成js对象当中的key
// 3 把这个对象 再还原成数组 // 把数组转成对象
function toObject(arr){
var obj = {} ; // 私有的对象
var j ;
for(var i=0 , j= arr.length ; i<j; i++){
obj[arr[i]] = true ;
}
return obj ;
} // 把这个对象转成数组
function keys(obj){
var arr = [] ; // 私有对象
for(var attr in obj){
if(obj.hasOwnProperty(attr)){
arr.push(attr);
}
}
return arr ;
} //综合的方法 去掉数组中的重复项
function uniq(newarr){
return keys(toObject(newarr));
} alert(uniq(arr));
去除数组重复项
3.继承案例
<script type=text/javascript> var __extends = this.__extends || function (sub, sup) {
for (var p in sup) if (sup.hasOwnProperty(p)) sub[p] = sup[p];//继承父类自身属性
function __() { this.constructor = sub; }
__.prototype = sup.prototype;
sub.prototype = new __(); alert(sub.prototype.constructor);
}; function extend(sub,sup){
var F=new Function();//创建一个空函数
F.prototype=sup.prototype;//空函数原型指向父类原型
sub.prototype=new F();
sub.prototype.constructor = sub;
sub.superClass =sup.prototype;//保持父类原型
//判断父类原型对象的构造器
if(sup.prototype.constructor==Object.prototype.constructor){
//如果简单原型覆盖 则手动添加
sup.prototype.constructor=sup;
}
} function Person(name,age){
this.name=name;
this.age=age;
}
Person.ff='sssc'; Person.prototype={
sayName : function(){
alert("对对")
}
} function Boy(name ,age,sex){
//或者 Boy.superClass.constructor.call(this,name,age)
Person.call(this,name,age);
this.sex=sex;
}
//Boy.prototype=new Person();
__extends(Boy,Person);//继承
var b=new Boy('对对',23,'男');
alert(b.name);
alert(b.age);
alert(b.sex);
b.sayName(); alert(Boy.prototype.constructor.ff);//输出父类自身属性 </script>
继承案例
4.链式编程
/***
* //简单的链式编程
* var person={
run:function(){
alert("跑");
return this;
},
jump:function(){
alert("跳");
return this; },
sleep:function(){
alert("睡");
return this;
}
} person.run().jump().sleep();
*/ (function(window,undefined){
//定义私有_$方法
function _$(arguments){
//正则表达式匹配id选择器
var idselector=/^#\w+$/;
this.dom //此属性接收所得到的元素.
if(idselector.test(arguments[0])){
this.dom=document.getElementById(arguments[0].substring(1));
}else{
throw Error (' arguments is error');
} }; //在Function上扩展一个可以实现链式编程的方法
Function.prototype.method=function(methodName,fn){
this.prototype[methodName]=fn;
return this; }; _$.prototype={
constructor:_$,
addEvent:function(type,fn){
if (window.addEventListener) { //ff
this.dom.addEventListener(type, fn);
}
else if (window.attachEvent) {//ie
this.dom.attachEvent("on"+type,fn); }
return this;
},
setStyle:function(property,val){
this.dom.style[property]=val;
return this;
} }; window.$=_$;
_$.onReady=function(fn){
//1.实例化出来_$对象 真正的注册到window上
window.$=function (){
return new _$(arguments); } ;
//2.执行代码
fn();
//3.实现链式编程
_$.method('addEvent',function(){
alert('111');
return this;
}).method('setStyle',function(){
alert('222');
return this;
}); _$.prototype.addEvent().setStyle(); } })(window) ; $.onReady(function(){
$("#inp").addEvent("dblclick",function(){
alert("双击");
}).setStyle("backgroundColor","red"); });
</script>
js链式编程
5.组合模式
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>组合模式</title>
<script type=text/javascript>
/***
*
* 公司-
* 部门1
* 人员1
* 人员2
* 人员3
* 部门2
* 人员4
* 人员5
* 人员6
*/ /***
*
* 普通方式实现
*/
var Org =function(name){
this.name=name;
this.depts=[];
}
Org.prototype={
constructor:Org,
addDepts:function(child){
this.depts.push(child);
return this;
},
getDepts:function(){
return this.depts;
}
} var Dept=function(name){
this.name=name;
this.persons=[];
};
Dept.prototype={
constructor:Dept,
addPersons:function(child){
this.persons.push(child);
return this;
},
getPersons:function(){
return this.persons; }
}; var Person=function(name){
this.name=name;
} Person.prototype={
constructor:Person,
work:function(){
document.write(this.name+'工作,');
}
} var p1=new Person('人员1')
var p2=new Person('人员2')
var p3=new Person('人员3')
var p4=new Person('人员4')
var p5=new Person('人员5')
var p6=new Person('人员6') var dept1=new Dept('部门1');
dept1.addPersons(p1).addPersons(p2).addPersons(p3);
var dept2=new Dept('部门2');
dept2.addPersons(p4).addPersons(p5).addPersons(p6); var org =new Org('yjq');
org.addDepts(dept1).addDepts(dept2); //循环工作
for(var i=0,depts= org.getDepts();i<depts.length;i++){
var dept=depts[i];
for(var j=0,persons=dept.getPersons();j<persons.length;j++){
if(persons[j].name ==='人员4'){
//persons[j].work();
}
}
}
//可维护性差 /***
* 组合模式方式实现
*
* 场景:
* 1.存在一批组织成某种层次体系的对象
* 2.希望对这批对象或其中的一部分对象实施一个操作
*
* 特点:
* 1.组合模式中只有两种类型对象:组合对象,叶子对象
* 2.这两中类型都实现同一批接口
* 3.一般我们会在组合对象中调用其他方法并隐式调用'下级对象'的方法(递归)
*/ var Composite=function(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){
//接收叶子对象
var elements=[]; //判断对象是否为Leaf类型的,是则添加到数组,否则继续递归
var pushLeaf=function(item){
if(item.type=='Composite'){
item.children.forEach(arguments.callee);
}else if(item.type==='Leaf'){
elements.push(item);
}
};
//根据name 让指定name下所有的类型为Leaf的对象执行
if(name&& this.name!==name){
this.children.forEach(function(item){ //如果传递的name是2级节点名称
if(item.name===name&&item.type==='Composite'){
item.children.forEach(pushLeaf);
}
//如果name是3级,4级.....节点
if(item.name!==name&&item.type==='Composite'){
item.children.forEach(arguments.callee);
} //如果传递的name是叶子节点的时候
if(item.name===name&&item.type==='Leaf'){
elements.push(item);
}
}); }else{//不传递name 则是整个公司leaf
this.children.forEach(pushLeaf);
} //返回
return elements; },
work:function(name){
//获取leaf类型对象节点
var leafObjects=this.getChild(name);
for(var i=0;i<leafObjects.length;i++){
leafObjects[i].work();
}
}
} var Leaf=function(name){
this.name=name;
this.type='Leaf';//说明对象类型
} Leaf.prototype={
constructor:Leaf,
addChild:function(child){
throw new Error('error');
},
getChild:function(name){
if(this.name=name){
return this;
}
return null;
},
work:function(){
document.write(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('部门1');
_dept1.addChild(_p1).addChild(_p2).addChild(_p3);
var _dept2=new Composite('部门2');
_dept2.addChild(_p4).addChild(_p5).addChild(_p6); var _dept3=new Composite('部门3');
_dept3.addChild(_p7).addChild(_p8).addChild(_p9);
var _dept4=new Composite('部门4');
_dept4.addChild(_p10).addChild(_p11).addChild(_p12); var org1 =new Composite('公司1');
org1.addChild(_dept1).addChild(_dept2);
var org2 =new Composite('公司2');
org2.addChild(_dept3).addChild(_dept4); var org =new Composite('公司');
org.addChild(org1).addChild(org2);
org.work('公司1');
</script>
</head>
<body>
</body>
</html>
js组合模式
6.装饰者模式
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>装饰者模式</title>
<script type=text/javascript>
/***
* 装饰者(decorator)模式
* 作用:为对象添加新特性;
* 实现:
* 1.实现同样的接口(具有相同的方法)
* 2.需要有子类
* 3.子类需要接收父类的的引用
* 简单的说就是:需要装饰的类(父类)把它的引用传递给装饰类(子类)让装饰类装饰
*/
var Car =function(car){
//为了让子类继承(让子类多一个父类的引用)
this.car=car;
};
Car.prototype={
constructor:Car,
getPrice:function(){
return 1000;
},
assemble:function(){
alert('car');
}
}; //新需求:加车灯 需要加钱(方法改变) var LightDecorator=function(car){ //原始对象
Car.call(this,car);//借用构造函数继承
}
LightDecorator.prototype=new Car();//原型继承 LightDecorator.prototype={
constructor:LightDecorator,
//重写父类方法
getPrice:function(){
return this.car.getPrice()+11; //继承过来的car 有父类的引用 加钱11
},
assemble:function(){
alert('LightCar');
}
} //需要加其他的
var OtherDecorator=function(car){ //原始对象
Car.call(this,car);//借用构造函数继承
}
OtherDecorator.prototype=new Car();//原型继承 OtherDecorator.prototype={
constructor:OtherDecorator,
//重写父类方法
getPrice:function(){
return this.car.getPrice()+1; //继承过来的car 有父类的引用 加钱1
},
assemble:function(){
alert('OtherCat');
}
} var car =new Car();
alert(car.getPrice());
car.assemble(); car =new LightDecorator(car);
alert(car.getPrice());
car.assemble(); car =new OtherDecorator(car);
alert(car.getPrice());
car.assemble(); //返回一个当前时间的字符串表示形式
function getDate() {
return new Date().toString();
} function upperCaseDecorator(fn){
return function(){
return fn.apply(this,arguments).toUpperCase();
}
} alert(getDate());
alert(upperCaseDecorator(getDate)());
</script>
</head>
<body>
</body>
</html>
js装饰者模式
7.桥接模式
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>桥接模式</title>
<script type="text/javascript">
/**
* 桥接模式:主要是把抽象和实现分离,使它们完全独立
*/
var PublicClass= function(){
//私有化变量
var privateMethod =function(){
alert('do something....');
} //可单元测试
privateMethod(); //通过特权函数去访问这个私有的独立单元
this.bridgeMethod=function(){
return privateMethod();
}
}; var p = new PublicClass();
p.bridgeMethod(); </script>
</head>
<body>
</body>
</html>
js桥接模式
8.观察者模式
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>观察者模式</title>
<script type=text/javascript>
/**
* 观察者模式:对程序中的某一个对象的进行实时的观察,当该对象状态发生改变的时候 进行通知
* 观察者、被观察者
* 案例:订报纸 (报社:发布者、订阅者)
*/
//发布者(被观察者)
var Publish=function(name){
this.name=name;
this.subscribers=[];//接受所以的订阅者(每一个元素是函数的类型fn)数组
}; //Publish类的实例对象去发布消息的方法
Publish.prototype.deliver=function(news){
var publish=this;
this.subscribers.forEach(function(fn){
fn(news,publish);//把消息发给一个订阅者
});
return this;//链式编程
} //具体的一个订阅者去订阅报纸的方法
Function.prototype.subscribe=function(publish){
var sub =this;//取得具体订阅者这个人
//some方法:循环遍历数组的每一个元素,执行一个函数,如果其中有一个返回true,那么整天返回true
var alreadyExists =publish.subscribers.some(function(item){
return item===sub;
});
//如果当前出版社里不存在这个人,则将其加入其中
if(!alreadyExists){
publish.subscribers.push(this);
}
return this;//链式编程
} //具体的一个订阅者去取消订阅报纸的方法
Function.prototype.unsubscribe=function(publish){
var sub=this;//具体的这个人
//filter:过滤函数,循环遍历数组的每一个元素,执行一个函数如果不匹配,则删除该元素
publish.subscribers=publish.subscribers.filter(function(itme){
return item!==sub;
});
return this;//链式编程
} window.onload=function(){
//实例化发布者对象(报社对象、被观察者)
var pub1=new Publish('报社1');
var pub2=new Publish('报社2');
var pub3=new Publish('报社3'); //观察者(订阅者)
var sub1 = function(news){
document.getElementById('sub1').innerHTML+=arguments[1].name+':'+news+'/n';
};
var sub2 = function(news){
document.getElementById('sub2').innerHTML+=arguments[1].name+':'+news+'/n';
}; //执行订阅的方法
sub1.subscribe(pub1).subscribe(pub2).subscribe(pub3);
sub2.subscribe(pub1).subscribe(pub2); //事件绑定
YJQ.EventHelper.addHandler(document.getElementById('pub1'),'click',function(){
pub1.deliver(document.getElementById('text1').value);
});
YJQ.EventHelper.addHandler(document.getElementById('pub2'),'click',function(){
pub2.deliver(document.getElementById('text2').value);
});
YJQ.EventHelper.addHandler(document.getElementById('pub3'),'click',function(){
pub3.deliver(document.getElementById('text3').value);
}); }
</script>
</head>
<body>
<input id="pub1" type="button" value="报社1"/><input id="text1" value=""/><br/>
<input id="pub2" type="button" value="报社2"/><input id="text2" value=""/><br/>
<input id="pub3" type="button" value="报社3"/><input id="text3" value=""/><br/> <textarea id="sub1" rows="5" cols="30"></textarea>
<textarea id="sub2" rows="5" cols="30"></textarea>
</body>
<script type=text/javascript>
var YJQ={};
YJQ.EventHelper={
addHandler:function(element,type,handler){
if(element.addEventListener){ //FF
element.addEventListener(type,handler,false);
}else if(element.attachEvent){//IE
element.attachEvent('on'+type,handler);
}
},
removeHandler:function(element,type,handler){
if(element.addEventListener){ //FF
element.removeEventListener(type,handler,false);
}else if(element.attachEvent){//IE
element.detachEvent('on'+type,handler);
}
} } </script>
</html>
js观察者模式
9.代理模式
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>代理模式</title>
<script type=text/javascript>
/**
* 代理模式(proxy):代理也是对象,它的目的就是为了节制(控制)对本体对象的访问
* 代理对象和另一个对象(实体对象)实现的是同样的接口,实际上工作还是实体在做
*/ var Book=function(id,title,author){
this.id=id;
this.title=title;
this.author=author;
};
//图书馆(本体对象,实例化图书馆需要消耗很多的资源)
var Library=function(books){
this.books=books;
}
Library.prototype={
constructor:Library,
addbook:function(book){
this.books[book.id]=book;
},
findbook:function(id){
if(this.books[id]){
return this.books[id];
}
return null;
},
checkoutbook:function(id){
return this.findbook(id);
},
returnbook:function(book){
this.books[book.id]=book;
}
} //图书馆的代理对象
var LibraryProxy=function(books){
this.books=books;
this.libray=null;//定义一个空对象
}
LibraryProxy.prototype={
constructor:LibraryProxy, //初始化Library
initializeLibrary:function(){
if(this.libray==null){
this.libray=new Library(this.books);
}
},
addbook:function(book){
this.initializeLibrary();
this.libray.books[book.id]=book;
},
findbook:function(id){
this.initializeLibrary();
if(this.libray.books[id]){
return this.libray.books[id];
}
return null;
},
checkoutbook:function(id){
this.initializeLibrary();
return this.libray.findbook(id);
},
returnbook:function(book){
this.initializeLibrary();
this.libray.books[book.id]=book;
}
} var proxy=new LibraryProxy({
'1':new Book('1','c#','y'),
'2':new Book('2','js','z'),
});
alert(proxy.findbook('1').title);//c#
</script>
</head>
<body>
</body>
</html>
js代理模式
10.单例模式
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>单例模式</title>
<script type=text/javascript>
//单例模式(singliton)
//1.简单单例
var Singliton={
name:'yjq',
age:'23',
sayHello:function(){
alert('hello');
}
};
alert(Singliton.name);
Singliton.sayHello();
//另一个作用 :划分命令空间 //2.借用闭包创建单例:闭包主要的目的 保护数据
//命名空间
var YJQ ={};
YJQ.Singleton=(function(){
//添加自己的私有成员
var name = 'yjq';
var age ='23'; //把块级作用域里的执行结果赋值给单体对象
return {
name:name,
age:age,
sayHello:function(){
alert('hello');
}
};
})();
alert(YJQ.Singleton.name);
YJQ.Singleton.sayHello(); //3.惰性单例(常用)
var Ext={};
Ext.Base=(function(){
//私有变量 控制返回的单例对象
var uniqInstance; //undefined //需要一个构造器 init初始化单例对象的方法
function init(){
//私有成员变量
var name = 'yjq';
var age = '23';
var sayHello = function(){
alert('hello');
} return {
name: name,
age: age,
sayHello: sayHello
}
} return {
getInstance :function(){
if(!uniqInstance){//如果不存在 创建单例对象
uniqInstance = init();
}
return uniqInstance;
}
};
})();
Ext.Base.getInstance().sayHello(); //4.分支单例(判断程序的分支)(常用)
var def =true;
Ext.More =(function(){
var objA ={}; //ff
var objB ={}; //ie
return (def)?ojbA:ojbB;
})();
</script>
</head>
<body>
</body>
</html>
js单例模式