收藏的js学习小例子
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); });
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>
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>
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>
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>
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>
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>
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>

浙公网安备 33010602011771号