• 面向对象及组件开发---笔记1


    1、什么是面向对象编程
    •用对象的思想去写代码,就是面向对象编程
    • 过程式写法
    • 面向对象写法
    过程式写法如下
    function test(){}
    for(){}
    if(){}

    • 我们一直都在使用对象

    如数组 Array  时间 Date都是对象
    //创建
    var arr = new Array(); //[]  ,底下分别有些方法
    var date = new Date();  
    //arr的方法
    arr.length
    arr.push();
    arr.sort();
    //date的方法
    date.getDate();
    我们把系统自带的对象,叫做系统对象
    • 面向对象编程(OOP)的特点  最好的学习方法就是多练习
    • 抽象:抓住核心问题 抽是抽取,象是具象
    • 封装:只能通过对象来访问方法
    • 继承:从已有对象上继承出新的对象  其实就是复用代码
    • 多态:多对象的不同形态  复用的另外一种形式,但是用的不多,因js语言是弱类型类型

    • 对象的组成

    • 方法(行为、操作)——函数:过程、动态的
    • 属性——变量:状态、静态的
    属性和方法的区别
    //系统对象下的数组
    var arr = [];//对象
    arr.number = 10;  //对象下面的变量:叫做对象的属性
    //alert( arr.number );
    //alert( arr.length );
    arr.test = function(){  //把一个函数写在对象下面,或者说对象下面的函数 : 叫做对象的方法
        alert(123);
    };
    arr.test();
    //以下是常见的方法,加括号的是方法,不加是属性
    arr.push();
    arr.sort();

    2、创建第一个面向对象程序

        •为对象添加属性和方法
           –Object对象
            –this指向
            –创建两个对象 : 重复代码过多

     以下是一个完成的面向对象的程序

    var obj=new Object(); //创建了一个空的对象
    obj.name='小明'; //创建的属性
    obj.showName=function(){ //创建的方法
        alert(this.name);
    }
    obj.showName();//调用

    面向对象中难点this指向,谁调用的就是指向谁

    3.工厂方式与构造函数

    工厂方式 其实就是封装函数

    1.面向对象中的封装函数

    • //工厂方式 : 封装函数
      function creatName(name){
          //1.原料
          var obj=new Object();
          //2.加工
          obj.name=name;
          obj.showName=function(){
              alert( this.name ); //此时this的指向是window
          }
          //3.出场
          return obj;
      }
      var p1 = creatName('小明');//创建对象
      p1.showName();             //调用方法
      var p2 = creatName('小强');
      p2.showName();

    2.改成与系统对象类似写法

      • 首字母大写
      • New 关键字提取
      • This指向为新创建的对象
    //当new去调用一个函数 : 这个时候函数中的this就是创建出来的对象,而且函数的的返回值直接就是this啦(隐式返回)
    //new后面调用的函数 : 叫做构造函数
    function CreatePerson(name){    
        this.name = name;
        this.showName = function(){
            alert( this.name );
        };
        }
    var p1 = new CreatePerson('小明');
    p1.showName();
    var p2 = new CreatePerson('小强');
    p2.showName();
    
    alert( p1.showName == p2.showName );  //false 
    3.构造函数的定义
    • 用来创建对象的函数,叫做构造函数
    4.存在的问题
    • 对象的引用
    • 浪费内存

    为什么p1和p2是false,这和类型的传递有关,内存和值都相等才相等

     基本类型 : 赋值的时候只是值的复制
    var a = 5;
    var b = a;
    b += 3;
    alert(b); //8
    alert(a); //5   基本类型 : 赋值的时候只是值的复制
    对象类型 : 赋值不仅是值的复制,而且也是引用的传递
    var a = [1,2,3];
    var b = a;
    b.push(4);
    alert(b);  //[1,2,3,4]
    alert(a);  //[1,2,3,4]   对象类型 : 赋值不仅是值的复制,而且也是引用的传递
    var a = [1,2,3];
    var b = a;
    b = [1,2,3,4];
    alert(b); //[1,2,3,4]
    alert(a); //[1,2,3]
    
    var a = 5;
    var b = 5;
    alert(a == b);  //true基本类型 : 值相同就可以
    
    var a = [1,2,3];
    var b = [1,2,3];
    alert( a == b );  //false  //对象类型 : 值和引用都相同才行
    
    var a = [1,2,3];
    var b = a;
    alert( a==b );  //true
    5.原型 :作用是去改写对象下面公用的方法或者属性 , 让公用的方法或者属性在内存中存在一份 ( 提高性能 )
    3原型-prototype
     
         • 概念
     
           –重写对象方法,让相同方法在内存中存在一份(提高性能)
     
         • 学习原型
     
            –类比  :  CSS中的Class  
     
    • 原型 : CSS中的class
    • 普通方法 : CSS中的style
    //CSS中的style 普通写法
    
    var arr = [1,2,3,4,5];
    var arr2 = [2,2,2,2,2];
    
    arr.sum = function(){
        
        var result = 0;
        for(var i=0;i<this.length;i++){
            result += this[i];
        }
        return result;
        
    };
    arr2.sum = function(){
        
        var result = 0;
        for(var i=0;i<this.length;i++){
            result += this[i];
        }
        return result;
        
    };
    alert( arr.sum() );  //15
    alert( arr2.sum() ); //10

        普通写法再一定情况下会代码冗长,重复

    • 通过原型改写工厂方式

    
    
            –原则 
    
    
    »相同的属性和方法可以加载原型上
    
    
    »混合的编程模式
    原型 : prototype : 要写在构造函数的下面
    改写以上求和代码
    var arr = [1,2,3,4,5];
    var arr2 = [2,2,2,2,2];
    
    Array.prototype.sum = function(){
        var result = 0;
        for(var i=0;i<this.length;i++){
            result += this[i];
        }
        return result;
    };
    
    alert( arr.sum() );  //15
    alert( arr2.sum() );  //10

    相同情况下普通写法style方式的优先级会比原型高

    var arr = [];
    arr.number = 10;
    Array.prototype.number = 20;
    alert(arr.number); //10

       •总结面向对象写法

    -----构造函数加属性,原型加方法 
    function CreatePerson(name){
        this.name = name;
    }
    CreatePerson.prototype.showName = function(){
        alert( this.name );
    };
    var p1 = new CreatePerson('小明');
    //p1.showName();
    var p2 = new CreatePerson('小强');
    //p2.showName();
    alert( p1.showName == p2.showName );  //true  再内存中只存在一份
    面向对象的写法 按照下面的方式进行练习
    <script>
    function 构造函数(){
        this.属性
    }
    构造函数.原型.方法 = function(){};

    //使用
    var 对象1 = new 构造函数(); 对象1.方法(); </script>

    举例:面向对象的选项卡

       • 原则
               –先写出普通的写法,然后改成面向对象写法
    布局
    <style>
    #div1 div{ width:200px; height:200px; border:1px #000 solid; display:none;}
    .active{ background:red;}
    </style>
    <script>
    </script>
    </head>
    
    <body>
    <div id="div1">
        <input class="active" type="button" value="1">
        <input type="button" value="2">
        <input type="button" value="3">
        <div style="display:block">11111</div>
        <div>22222</div>
        <div>33333</div>
    </div>
    </body>
    </html>

    步骤一:普通写法

    window.onload = function(){
        var oParent = document.getElementById('div1');
        var aInput = oParent.getElementsByTagName('input');
        var aDiv = oParent.getElementsByTagName('div');
        
        for(var i=0;i<aInput.length;i++){
            aInput[i].index = i;
            aInput[i].onclick = function(){
                for(var i=0;i<aInput.length;i++){
                    aInput[i].className = '';
                    aDiv[i].style.display = 'none';
                }
                this.className = 'active';
                aDiv[this.index].style.display = 'block';
            };
        }
        
    };

    步骤二:.开始改写:原则

       》》. 普通方法变型
          • 尽量不要出现函数嵌套函数
          • 可以有全局变量 ,把局部的变成全局的变量
          • 把onload中不是赋值的语句放到单独函数中
    
    
    var oParent = null;
    var aInput = null;
    var aDiv = null;
    
    window.onload = function(){
    
        oParent = document.getElementById('div1');
        aInput = oParent.getElementsByTagName('input');
        aDiv = oParent.getElementsByTagName('div');
    
        init();
    
    };
    
    function init(){
        for(var i=0;i<aInput.length;i++){
            aInput[i].index = i;
            aInput[i].onclick = change;
        }
    }
    
    function change(){
        for(var i=0;i<aInput.length;i++){
            aInput[i].className = '';
            aDiv[i].style.display = 'none';
        }
        this.className = 'active';
        aDiv[this.index].style.display = 'block';
    }
    步骤三:»改成面向对象
    • 全局变量就是属性
    • 函数就是方法
    • Onload中创建对象 进行调用
    • 改this指向问题: 事件或者是定时器,尽量让面向对象中的this指向对象
    oDiv.onclick = function(){
        this : oDiv
    };
    
    
    oDiv.onclick = show;
    function show(){
        this : oDiv
    }
    
    
    oDiv.onclick = function(){
        show();
    };
    function show(){
        this : window
    }

    this的指向特别容易出问题

    window.onload = function(){    
        var t1 = new Tab();
        t1.init();
    };
    
    function Tab(){
        this.oParent = document.getElementById('div1');
        this.aInput = this.oParent.getElementsByTagName('input');
        this.aDiv = this.oParent.getElementsByTagName('div');
    }
    
    Tab.prototype.init = function(){
        var This = this;
        for(var i=0;i<this.aInput.length;i++){
            this.aInput[i].index = i;
            this.aInput[i].onclick = function(){
                This.change(this);
            };
        }
    };
    
    Tab.prototype.change = function(obj){
        for(var i=0;i<this.aInput.length;i++){
            this.aInput[i].className = '';
            this.aDiv[i].style.display = 'none';
        }
        obj.className = 'active';
        this.aDiv[obj.index].style.display = 'block';
    };

    面向对象适合复杂开发,很简单的开发其实不太适合,不然反而代码更加冗长

    <div id="div1">
        <input class="active" type="button" value="1">
        <input type="button" value="2">
        <input type="button" value="3">
        <div style="display:block">11111</div>
        <div>22222</div>
        <div>33333</div>
    </div>
    
    <div id="div2">
        <input class="active" type="button" value="1">
        <input type="button" value="2">
        <input type="button" value="3">
        <div style="display:block">11111</div>
        <div>22222</div>
        <div>33333</div>
    </div>
    window.onload = function(){
        
        var t1 = new Tab('div1');
        t1.init();
        t1.autoPlay();
        
        var t2 = new Tab('div2');
        t2.init();
        t2.autoPlay();
        
    };
    
    function Tab(id){
        this.oParent = document.getElementById(id);
        this.aInput = this.oParent.getElementsByTagName('input');
        this.aDiv = this.oParent.getElementsByTagName('div');
        this.iNow = 0;
    }
    
    Tab.prototype.init = function(){
        var This = this;
        for(var i=0;i<this.aInput.length;i++){
            this.aInput[i].index = i;
            this.aInput[i].onclick = function(){
                This.change(this);
            };
        }
    };
    
    Tab.prototype.change = function(obj){
        for(var i=0;i<this.aInput.length;i++){
            this.aInput[i].className = '';
            this.aDiv[i].style.display = 'none';
        }
        obj.className = 'active';
        this.aDiv[obj.index].style.display = 'block';
    };
    
    Tab.prototype.autoPlay = function(){
        
        var This = this;
        
        setInterval(function(){
            
            if(This.iNow == This.aInput.length-1){
                This.iNow = 0;
            }
            else{
                This.iNow++;
            }
            
            for(var i=0;i<This.aInput.length;i++){
                This.aInput[i].className = '';
                This.aDiv[i].style.display = 'none';
            }
            This.aInput[This.iNow].className = 'active';
            This.aDiv[This.iNow].style.display = 'block';
            
            
        },2000);
        
    };

    面向对象其实就是模仿系统对象的一些行为

    var arr = [4,7,1,3];
    arr.sort();  // 1 3 4 7
    
    var arr2 = [4,7,1,3];
    arr2.push(5);
    arr2.sort(); // 1 3 4 5 7

    知识点:

    1. 理解面向对象
    2. JS中对象的组成
    3. 用工厂方法创建一个对象
    4. 原型的概念和使用
    5. 修改系统对象(及原型)
    6. 混合的构造函数/原型方式
  • 相关阅读:
    Educational Codeforces Round 13 E. Another Sith Tournament 概率dp+状压
    Codeforces Round #358 (Div. 2) D. Alyona and Strings 字符串dp
    Codeforces Round #359 (Div. 2) D. Kay and Snowflake 树的重心
    Codeforces Round #311 (Div. 2) D. Vitaly and Cycle 奇环
    Codeforces Round #Pi (Div. 2) E. President and Roads 最短路+桥
    Codeforces Gym 100342J Problem J. Triatrip 三元环
    HDU 4587 TWO NODES 割点
    hdu 5615 Jam's math problem(十字相乘判定)
    C++数组作为函数参数的几个问题(转)
    UVA
  • 原文地址:https://www.cnblogs.com/eveblog/p/4853526.html
Copyright © 2020-2023  润新知