zoukankan      html  css  js  c++  java
  • JS面向对象思想(OOP)

    JS面向对象思想(OOP)

    直接看js好了,模拟创建一个奥运会

    复制代码
    function 奥运会Class(主题) {
    
       // 删除主题
       // delete  this.主题;
    
        this.主题 = 主题;
        this.开幕时间;
        this.闭幕时间;
        this.公告簿 = "";
    
        //模拟开幕
        this.开幕 = function () {
            this.开幕时间 = "2012年7月28日03时12分(北京时间)";
            this.公告薄 = "奥运主题:" + this.主题 + "
    " + "开幕时间:" + this.开幕时间 + "
    " + "伦敦奥运会开幕了
    ";
            this.公告发布event(this, this.公告薄);
        }
    
        //模拟闭幕
        this.闭幕 = function () {
            this.闭幕时间 = "2012年8月13日 04:00(北京时间)";
            this.公告薄 += this.闭幕时间 + "伦敦奥运会闭幕了
    ";
            this.公告发布event(this, this.公告薄);
        }
    
        //模拟事件的方法
        this.公告发布event = function(sender, e) {
        }
    
        //构建集合对象
        this.国家集合 = new Array();
        this.运动员集合 = new Array();
        this.裁判集合 = new Array();
        this.项目集合 = new Array();
    
    
    
    
        //创建一个通用查询
        this.通用查询 = function (对象源, 查询集合对象名称, 查询字段, value) {
            for (var aa in 对象源) {
                if (aa == 查询集合对象名称) {
                    var source = 对象源[aa];
                    if (aa == 查询集合对象名称) {
                        for (var i = 0; i <= source.length; i++) {
                            var s = source[i.toString()];
                            if (s[查询字段] == value) {
                                return s;
                            }
                        }
                    }
                }
            }
            return null;
        }
    
    }
    
    
    
    
    //闭包扩展,在原型上扩展方法
    奥运会Class.prototype.添加国家 = function(国家名称, 地区) {
        var 国家 = new 国家Class(国家名称, 地区);//创建国家
        国家.所属奥运会 = this;
        this.国家集合.push(国家);//添加国家到国家集合
        this.公告簿 += 国家名称 + "  " + 地区 + "   " + "已经加入本届奥运会
    ";;//发布消息
        this.公告发布event(this, this.公告簿);
        //动态移除成员 或者是方法等 
        //  delete  this.公告簿; 
        //链式编程,进行优化
        return this;
    }
    
    奥运会Class.prototype.添加项目 = function(项目名称) {
        var 项目 = new 项目Class(项目名称);//创建项目
        项目.所属奥运会 = this;
        this.项目集合.push(项目);//添加项目到国家项目
    
        //发布消息
        this.公告簿 += 项目名称 + "  " + "已经加入本届奥运会" + "  Number:" + this.项目集合.length + "
    ";//发布消息
        this.公告发布event(this, this.公告簿);
        return this;
    }
    
    
    奥运会Class.prototype.添加裁判 = function(名称, 所属项目) {
        var 裁判 = new 裁判Class(名称);//创建裁判
        裁判.所属奥运会 = this;
        裁判.所属的项目 = 所属项目;
        this.裁判集合.push(裁判);//添加裁判到裁判集合
    
        //发布消息
        this.公告簿 += 名称 + "  " + "裁判已经加入本届奥运会" + "  Number:" + this.裁判集合.length + "
    ";
        this.公告发布event(this, this.公告簿);
        return this;
    }
    
    
    奥运会Class.prototype.添加运动员 = function(名称, 国家) {
        var 运动员 = new 运动员Class(名称, 国家);//创建运动员
        运动员.所属奥运会 = this;
        this.运动员集合.push(运动员);//添加运动员到运动员集合
        国家.添加运动员(运动员);
    
        //发布消息
        this.公告簿 += 名称 + "  " + "加入本届奥运会" + "  Number:" + this.运动员集合.length + "
    ";
        this.公告发布event(this, this.公告簿);
        return this;
    }
    
    
    
    //国家对象
    function 国家Class(国家名称, 地区) {
        this.名称 = 国家名称;
        this.地区 = 地区;
        this.所属奥运会 = null;
    
        this.运动员集合 = new Array();
        this.添加运动员 = function(运动员) {
            this.运动员集合.push(运动员);
        }
    }
    
    
    // 运动员对象
    function 运动员Class(姓名, 所属国家) {
        this.姓名 = 姓名;
        this.所属奥运会 = null;
        this.项目集合 = new Array();
        this.所属国家 = 所属国家;
    
        this.添加项目 = function(项目) {
            this.项目集合.push(项目);
            项目.所属运动员集合.push(this);
        }
    }
    
    
    //裁判对象
    function 裁判Class(姓名) {
        this.姓名 = 姓名;
        this.所属奥运会 = null;
        this.所属的项目 = null
    }
    
    //项目对象
    function 项目Class(名称) {
        this.名称 = 名称;
        this.所属奥运会 = null;
        this.成绩 = "";
        this.奖牌 = "";
        this.所属裁判 = null;
    
        this.所属运动员集合 = new Array();
    
        this.设置比赛成绩 = function() {
        }
    
    
    
        this.浅表克隆 = function() {
            var clone = new 项目Class();
            for (var a in this) {
                clone[a] = this[a];
            }
            return clone;
        }
    
    
    
        this.添加比赛成绩 = function(所属运动员, 成绩单) {
            for (var i = 0; i <= this.所属运动员集合.length; i++) {
                if (this.所属运动员集合[i.toString()].姓名 == 所属运动员.姓名) {
                    var s = this.所属运动员集合[i.toString()];
    
                    for (var ii = 0; ii <= s.项目集合.length; ii++) {
                        if (s.项目集合[ii.toString()].名称 == 成绩单.名称) {
                            var ss = s.项目集合[ii.toString()];
                            s.项目集合[ii.toString()] = 成绩单;
    
                            this.所属奥运会.公告簿 += 所属运动员.姓名 + "  " + 成绩单.名称 + "  " + 成绩单.成绩 + "
    ";
                            this.所属奥运会.公告发布event(this, this.所属奥运会.公告簿);
                            return;
                        }
                    }
    
                }
            }
        }
    
    
    
    
    }
    复制代码
    复制代码
       <script src="OOP奥运会.js" type="text/javascript">
        </script>
    
        <script type="text/javascript">
     var 奥运会 = new 奥运会Class("游伦敦,看世界!!!!!!!");
    
        function Button2_onclick() {
         
            //消息发布
            奥运会.公告发布event = function (sender, e) {
                document.getElementById("TextArea1").value = e;
            }
            奥运会.开幕();
    }
    
        function Button3_onclick() {
            //消息发布
            奥运会.公告发布event = function (sender, e) {
                document.getElementById("TextArea1").value = e;
            }
            //依次添加国家地区
            /*  奥运会.添加国家("中国", "亚洲");
              奥运会.添加国家("日本", "亚洲");
              奥运会.添加国家("美国", "北美洲");
              奥运会.添加国家("德国", "欧洲");
              */
    
            //链式编程,可以这样写,也可以以上面的方式写
            奥运会.添加国家("中国", "亚洲").添加国家("日本", "亚洲").添加国家("美国", "北美洲").添加国家("德国", "欧洲");
    
        }
    
    function Button4_onclick() {
        //消息发布
        奥运会.公告发布event = function (sender, e) {
            document.getElementById("TextArea1").value = e;
        }
        //添加运动项目
        奥运会.添加项目("跳水").添加项目("举重").添加项目("柔道").添加项目("篮球").添加项目("排球").添加项目("田径");
    }
    
    function Button5_onclick() {
        //消息发布
        奥运会.公告发布event = function (sender, e) {
            document.getElementById("TextArea1").value = e;
        }
    //添加裁判
     奥运会.添加裁判("张三").添加裁判("李四").添加裁判("陈三");
     
    
        //为裁判添加运动项目
      var 跳水 = 奥运会.通用查询(奥运会 ,"项目集合" ,"名称","跳水");
      var 张三 = 奥运会.通用查询(奥运会 ,"裁判集合" ,"姓名","张三");
      跳水.所属裁判= 张三;
      张三.所属的项目 =跳水;
     
      var 举重 = 奥运会.通用查询(奥运会 ,"项目集合" ,"名称","举重");
      var 李四 = 奥运会.通用查询(奥运会 ,"裁判集合" ,"姓名","李四");
      举重.所属裁判= 李四;
      李四.所属的项目 =举重;
     
      var 柔道 = 奥运会.通用查询(奥运会 ,"项目集合" ,"名称","柔道");
      var 陈三 = 奥运会.通用查询(奥运会 ,"裁判集合" ,"姓名","陈三");
     柔道.所属裁判= 陈三;
     陈三.所属的项目 =柔道;
     
    }
    
    
    function Button6_onclick() {
        //消息发布
        奥运会.公告发布event = function (sender, e) {
            document.getElementById("TextArea1").value = e;
        }
        //创建运动员
        var 中国 = 奥运会.通用查询(奥运会, "国家集合", "名称", "中国");
        奥运会.添加运动员("郭晶晶", 中国);
    
        var 日本 = 奥运会.通用查询(奥运会, "国家集合", "名称", "日本");
        奥运会.添加运动员("小日本田", 日本);
    
        var 美国 = 奥运会.通用查询(奥运会, "国家集合", "名称", "美国");
        奥运会.添加运动员("布迪亚 ", 美国);
    for (var i = 0; i < 10; i++) {
    
        var 中国 = 奥运会.通用查询(奥运会, "国家集合", "名称", "中国");
        奥运会.添加运动员("郭晶晶"+i, 中国).添加运动员("Z-" + i, 中国).添加运动员("Z-G" + i, 中国);
    
        var 日本 = 奥运会.通用查询(奥运会, "国家集合", "名称", "日本");
        奥运会.添加运动员("小日本田"+i, 日本).添加运动员("R-" + i, 日本).添加运动员("R-B" + i, 日本);
    
        var 美国 = 奥运会.通用查询(奥运会, "国家集合", "名称", "美国");
        奥运会.添加运动员("布迪亚 "+i, 美国).添加运动员("U-" + i, 美国).添加运动员("U-S" + i, 美国);
    
    }
                    
    
    }
    
    function Button7_onclick() {
    
        //消息发布
        奥运会.公告发布event = function (sender, e) {
            document.getElementById("TextArea1").value = e;
        }
    
        //给运动员分配运动项目
    var 中国=奥运会.通用查询(奥运会 ,"国家集合" ,"名称","中国");
    var 郭晶晶=奥运会.通用查询(中国 ,"运动员集合" ,"姓名","郭晶晶");
    var 跳水 =奥运会.通用查询(奥运会 ,"项目集合" ,"名称","跳水");
    郭晶晶.添加项目(跳水);
    
    
    var 日本=奥运会.通用查询(奥运会 ,"国家集合" ,"名称","日本");
    var 小日本田=奥运会.通用查询(日本 ,"运动员集合" ,"姓名","小日本田");
    小日本田.添加项目(跳水);
    
    var 美国=奥运会.通用查询(奥运会 ,"国家集合" ,"名称","美国");
    var 布迪亚 =奥运会.通用查询(美国 ,"运动员集合" ,"姓名","布迪亚 ");
    布迪亚 .添加项目(跳水);
    
    }
    
    function Button8_onclick() {
        //消息发布
        奥运会.公告发布event = function (sender, e) {
            document.getElementById("TextArea1").value = e;
        }
        //为运动设置成绩
    var 中国=奥运会.通用查询(奥运会 ,"国家集合" ,"名称","中国");
    var 郭晶晶=奥运会.通用查询(中国 ,"运动员集合" ,"姓名","郭晶晶");
    var 跳水1 =奥运会.通用查询(奥运会 ,"项目集合" ,"名称","跳水").浅表克隆();
    
    //先得到要修改数据对象的引用
    var 跳水1set =奥运会.通用查询(郭晶晶 ,"项目集合" ,"名称","跳水");
    跳水1.成绩="99分";
    跳水1set.添加比赛成绩(郭晶晶,跳水1);
    
    
    var 日本=奥运会.通用查询(奥运会 ,"国家集合" ,"名称","日本");
    var 小日本田=奥运会.通用查询(日本 ,"运动员集合" ,"姓名","小日本田");
    var 跳水2 =奥运会.通用查询(奥运会 ,"项目集合" ,"名称","跳水").浅表克隆();
    
    var 跳水2set =奥运会.通用查询(小日本田 ,"项目集合" ,"名称","跳水");
    跳水2.成绩="25分";
    跳水2set.添加比赛成绩(小日本田,跳水2);
    }
    
    
    function Button9_onclick() {
    
        //消息发布
        奥运会.公告发布event = function (sender, e) {
            document.getElementById("TextArea1").value = e;
        }
        奥运会.闭幕();
    }
    
        </script>
    复制代码

    具体效果

    喜欢的人可以下载看看,体会OOP思想http://files.cnblogs.com/BABLOVE/JSOOP%E5%A5%A5%E8%BF%90%E4%BC%9A.rar

     

    使用avalon 实现一个序列号功能

    avalon“操作数据即操作DOM”的能力,让我们可以专致于业务,写出更专业,更优雅,更易维护的代码来。现在让我们看看如何实现一个序列号输入功能。它的需求以下:

    • 每输入4个字符就跳到下一个输入框。
    • 不能输入超过4个字符。
    • 支持复制贴粘功能,每4个字符自动对位到相应的输入框。

    先给出代码:

    <!DOCTYPE html>
    <html>
        <head>
            <title></title>
            <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
            <script src="avalon.js"></script>
            <style>
                input:focus{
                    border: 1px solid #a9ea00;
                    background:#f0f0f0;
                }
            </style>
            <script>
                var model = avalon.define("xxx", function(vm) {
                    vm.seriesNumber = [{value: ""}, {value: ""}, {value: ""}, {value: ""}]
                    vm.focusIndex = NaN
                    //获得焦点,实现输入框中的跳转操作
                    vm.focus = function(a, b) {
                        var el = this;
                        if (a === avalon(el).data("index")) {
                            setTimeout(function() {
                                el.focus()
                                el.select();
                            }, 0);
                        }
                    }
                    vm._focus = function() {
                        model.$unwatch()
                        model.focusIndex = avalon(this).data("index")
                        model.$watch()
                    }
     
                    //通过贴粘实现智能输入
                    vm.paste = function(e) {
                        var index = avalon(this).data("index")
                        var text = ""
                        if (e.clipboardData) {
                            avalon.log("w3c")
                            text = e.clipboardData.getData("text/plain");
                        } else if (window.clipboardData) {
                            avalon.log("ie")
                            text = clipboardData.getData("Text")
                        }
                        var array = text.match(/w{4}/g) || []
                        for (var i = 0; i < array.length; i++) {
                            var el = model.seriesNumber[index + i]
                            if (el) {
                                el.value = array[i]
                            }
                        }
                        var last = Math.min(index + i, 3)
                        setTimeout(function() {
                            model.focusIndex = last
                        }, 0)
     
                    }
     
                })
                //绑定$watch,实现输入字数限制与智能跳转
                model.seriesNumber.forEach(function(el, index) {
                    el.$watch("value", function(a, b) {
                        if (a.length >= 4) {
                            model.focusIndex = index + 1 //跳转
                            el.value = a.slice(0, 4)
                        }
                    })
                })
                //刚开始时聚焦到第一个输入框中
                avalon.ready(function() {
                    model.focusIndex = 0
                })
     
     
            </script>
        </head>
        <body>
            <div ms-controller="xxx" ms-each-el="seriesNumber">
                <input ms-duplex="el.value" ms-on-paste="paste" ms-focus="_focus" ms-bind="focusIndex: focus" ms-data-index="$index">
            </div>
            <h2>1234aaaabbbb6789</h2>
        </body>
    </html>

    首先,我们要监听一个input里面的内容变化,马上能想到用ms-duplex,该绑定能逐字符地监听变化。但由于存在多个INPUT,为了方便循环处理,我们用到一个数组。但数组VM中只能监听它的长度变化。因此整成对象数组,然后监听这些对象的某个字符串属性就行了。

    这个value值的变动,我们可以绑定$watch回调,当输入值超过4个字符串时,进行跳转操作。

    el.$watch("value", function(a, b) {
          if (a.length >= 4) {
              model.focusIndex = index + 1 //跳转
              el.value = a.slice(0, 4)
          }
      })

    如果实现跳转操作呢,我们使用另一个新属性focusIndex 来监听,当它变化时,我们再调用一个跳转方法。而这个跳转方法需要得到元素节点。这唯有万能绑定ms-bind 能干这事。

    ms-bind="vmProp:vmCallback"

    vmCallback的this指向被绑定元素,并传入此绑定属性的前后两个值。vmProp的值每次变动都会调用vmCallback。

    贴粘时,我们需要用到paste事件,但avalon默认没此绑定,需要用ms-on传入事件名,这里面做些兼容处理,逐一修改seriesNumber 数组对象的value 值就行了。

    例子
       

    1234aaaabbbb6789

    整个流程简单利落,除了跳转时我们用到一些DOM方法,其他都是对数据的操作。这与以往jQuery, Prototype.js, YUI的实现思路完全不同。打个比喻,avalon带来的技术体验,如同书法与打印机的区别。jQuery好优雅,能让你精确控制每一步DOM操作,DOM操作越是复杂,如同繁体字那样纵横捭阖,越是显得jQuery游刃有余。avalon好干净,不要准备文房四宝,一张A4,一台打印机就行了,刷刷地出来你要的东西,干脆利落,没什么人情味,但效率奇高,是工业革命的先声。从历史的发展过程来看,书法这种讲究技术,渗杂着许多人个品味地艺术被整齐划一的印刷术逼到一死角,被剥夺了文化传承者的角色。jQuery这些也一样,DOM操作最快,也比不上MVVM这种印刷机般的技术,后者能不着痕迹地同步视图,里面精密的算法保证不会存在冗余无用的DOM操作。前者还存在“糟糕的书法者”问题,最好的笔砚,在某些人手里也是潦草不堪,看守打印机工作就没这问题。从势利的角度来看,就是怎么能够给资本家带来好处,怎么在相对时间内能够有更多更快, 更稳定的产出,就怎么快被采纳,人性使然。


    相关文章

    利用avalon 实现一个简单的成绩单

     
     
     
    标签: avalon
     
    分类: javascript
  • 相关阅读:
    LeetCode:Multiply Strings
    c/c++ 输入输出缓冲区
    Scala access modifiers and qualifiers in detail
    PUT vs POST in REST
    Redis优化总结
    硬中断和软中断(转)
    Redis监控技巧(转)
    Understanding mysql max_connect_errors
    TCP : two different sockets sharing a port?
    libevent 安装异常
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3308003.html
Copyright © 2011-2022 走看看