收藏的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);
                });
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单例模式
原文地址:https://www.cnblogs.com/yangjingqi/p/4309719.html