• JS面向对象


    JS面向对象:

    JS面向对象基础:
      1.什么是面向对象:即在不了解某个对象内部原理的情况下,我们就可以直接使用它的功能
          使用面向对象时,我们只关注对象提供的功能,不关注内部的细节
          面向对象是一种通用思想,并非只是在编程中才能使用


      2.面向对象编程(OOP)的特点:
          --抽象:抓住核心问题,把与问题相关的特征抽出来,放到系统里面
          --封装:不考虑内部实现,只考虑使用功能
          --继承:从父类对象上继承一些方法/属性,子类又有字节的一些新的属性(分为多重继承,多态)


      3.对象的组成:
        1)--属性:与变量是等价的,平常我们定义的变量的特点:自由的不属于任何一个对象,
              而当一个变量属于某个对象时,我们就叫这个变量为属性.
            var a=12;     //变量:自由的,不属于任何一个事物
            alert(a);
            var arr=[1,2,3,4];
            arr.a=12;     //属性:不自由,是属于一个对象的变量
            alert(arr.a);


         2)--方法:与函数是等价的,平常所写的函数的特点:是自由的,
            而当一个函数属于某个对象时我们就叫这个函数为方法
              function aaa(){     //函数:自由的
                  alert('abc');
              }
              var arr=[1,2,3,4];
              arr.aaa=function(){   //方法:属于一个对象的函数
                  alert('abc');
              }
              aaa();
              arr.aaa();


      4.面向对象中的this:指当前的方法属于哪个对象,this就指的是那个对象
              (之前我们为对象添加一个事件,即为对象添加一个方法)


      5.面向对象中的window:当我们定义一个全局的方法/函数时,它是属于window之下的一个方法
          function show(){    //全局的函数/方法,属于window
              alert(this);    //弹出[object window]
          }
          ==>等价于:
          window.show=function(){
              alert(this);    //弹出[object window]
          }


      6.注意的问题:我们不能在系统对象(如Array,Date等)中随意添加属性,方法,否则会覆盖已有方法和属性
              我们经常用object对象来添加属性/方法,因为其几乎没有自己的属性和方法,可防止与添加的产生冲突


      7.自定义第一个面向对象的小程序:
          var obj=new Object();
          obj.name='yufan';
          obj.myQQ='123456';
          obj.show=function(){
              alert('我的姓名:'+this.name);
              alert('我的QQ:'+this.myQQ);
          }
          obj.show();    //调用


      当有多个用户时,以上方法就会有大量重复的代码,所以我们需要封装成一个函数
          function addPerson(name,qq){
              //原料
              var obj=new Object();
              //加工
              obj.name=name;
              obj.myQQ=qq;
              obj.show=function(){
                  alert('我的姓名:'+this.name);
                  alert('我的QQ:'+this.myQQ);
              }
              //出厂
              return obj;
          }
          var obj1=addPerson('yufan','123456');    //创建对象
          var obj2=addPerson('red','456789');    //再次创建对象
          obj1.show();    //调用对象上面的方法
          obj2.show();
          alert(obj1.show==obj2.show);    //false


      注**上面的概念理解:
          --上面的addPerson函数叫做:构造函数(和普通的函数没有区别,只不过他的作用不同而已)
          --上面构造函数创建过程的方式叫做工厂方式(有原料,有加工,有出厂)
          --工厂方式有缺点:
              --没有new
                   解决:当一个全局函数在调用时,前面加上new,则表示系统自己定义一个新对象
              --实例化对象时,每一个对象都有一个自己的方法,而这些对象的方法明明是一样的,却不能共用,会导致资源的浪费
                  (上面obj1.show==obj2.show-->false)
                  解决:用原型在所有创建的类上添加方法,使两个对象共用来自于原型上的方法
                  (这时有obj1.show==obj2.show-->true)

              js面向对象最终的代码是:
              function addPerson(name,qq){
                  //加new之后,系统自己会new一个对象出来,可不写:var this=new Object();
                  this.name=name;
                  this.myQQ=qq;
                  //加new之后,系统自己会返回一个对象出来,可不写:return this;
              }
              addPerson.prototype.show=function(){    //用原型在所用创建的类上添加方法
                  alert('我的姓名:'+this.name);
                  alert('我的QQ:'+this.myQQ);
              }
              var obj1=new addPerson('yufan','123456');
              var obj2=new addPerson('red','456789');
              obj1.show();
              obj2.show();
              alert(obj1.show==obj2.show);    //true
      总结面向对象创建的方法:
           在构造函数上给对象添加属性,在原型上给对象添加方法
             我们经常采用这种面向对象全新的写法:混合的构造函数/原型方式

      8.js原型(prototype):类似CSS里面的class,用class时,可以一次给多个元素添加行外样式,
        使用原型时,可以一次给多个实例化对象添加方法,使资源得到共用
          var arr1=new Array(12,5,3);
          var arr2=new Array(12,5,3,4);
          arr1.sum=function(){ //arr1.sum方法相当于CSS里添加行间样式,一次只能给一个元素添加样式
              var result=0;
              for(var i=0;i<this.length;i++){
                  result+=this[i];
              }
              return result;
          }
          arr1.sum();    //正确
          arr2.sum();    //会报错,因为没有为arr2添加sum方法
      ==>这时使用原型可以为多个对象添加方法,类似CSS里用class添加行外样式
          var arr1=new Array(12,5,3);
          var arr2=new Array(12,5,3,4);
          Array.prototype.sum=function(){  //prototype原型在类上添加方法
              var result=0;
              for(var i=0;i<this.length;i++){
                  result+=this[i];
              }
              return result;
          }
          arr1.sum();    //正确
          arr2.sum();    //正确
      注**对象和类的区别
          var arr=new Array(1,2,3);
          --类:模子-->Array
          --对象:成品(产品)-->arr
          --prototype原型是往类里面加东西(Array.prototype.sum),而不是对象


    js面向对象实例:
    1.将一个面向过程的程序,改写成面向对象的形式
        --原则:不能有函数套函数,但可以有全局变量
    2.过程:将平时写的面向过程的js选项卡,改写成面向对象的js选项卡
        --解决函数嵌套的问题(将嵌套的函数拿出来,放到外面,变成全局函数)
        --解决局部变量的问题,当局部变量在多个函数中使用时,将局部变量变成全局变量(否则会报错)
        --将window.onload(作用:初始化整个程序)变成 构造函数(作用:初始化整个对象)
        --将全局变量变成 -->对象的属性
        --将全局的函数变成 -->对象的方法

      

    面向过程的js选项卡,改写成面向对象的js选项卡
    CSS代码:
    <style> .active{ background: red; } #div1 div{ 200px; height: 200px; background: #ccc; border:1px solid #000; display: none; margin-top: 20px; } </style> HTML代码: <div id="div1"> <input class="active" type="button" value="首页" /> <input type="button" value="新闻" /> <input type="button" value="咨询" /> <input type="button" value="教育" /> <div style="display: block;">1111</div> <div>2222</div> <div>3333</div> <div>4444</div> </div> JS代码: window.onload=function(){ var obj=new TabSwitch('div1'); }; function TabSwitch(id){ var _this=this; var oDiv=document.getElementById(id); this.aBtn=oDiv.getElementsByTagName('input'); this.aDiv=oDiv.getElementsByTagName('div'); for (var i = 0; i < this.aBtn.length; i++) { this.aBtn[i].index=i; this.aBtn[i].onclick=function(){ _this.btnClick(this); } } } TabSwitch.prototype.btnClick=function(oBtn){ for (var i = 0; i < this.aBtn.length; i++) { this.aBtn[i].className=''; this.aDiv[i].style.display='none'; } oBtn.className='active'; this.aDiv[oBtn.index].style.display='block'; }

    3.改错:this,事件,闭包,传参

    js面向对象高级:
    1.json实现的面向对象:(又称单体)
        var json={
            name:'yufan',
            qq:'123456',
            showName:function(){
                alert('我的名字叫:'+this.name);
            },
            showQQ:function(){
                alert('我的QQ是:'+this.qq);
            }
        }
        json.showName();
        json.showQQ();
    与OOP的方法相比json实现的创建对象优点是简单,但是该方法只适用创建单个对象,不适合多个对象
    Json方式实现的对象的适用范围:
        --整个程序里只有一个对象,写起来比较简单


    2.命名空间:可以让很多相同名字的函数同时存在
        --使用时,把方法包在一个json里面
          var zns={};
          zns.common={};
          zns.ms={};
          zns.color={};
          zns.common.getUser=function(){
              alert('a');
          }
         zns.ms.getUser=function(){
              alert('b');
          }
          zns.color.getUser=function(){
              alert('c');
          }
          zns.common.getUser();
          zns.ms.getUser();
          zns.color.getUser();

    3.js中的引用问题:(函数不会出现js引用问题)
        当把arr1给arr2时,计算机为了节约空间,会把arr1与arr2同时指向一个内存空间
        而不是复制一份再赋给arr2,所以当改变arr2时,arr1也会发生改变,这个就叫js引用
         var arr1=[1,2,3];
         var arr2=arr1;
         arr2.push(4);
         alert(arr1);    //1,2,3,4
         alert(arr2);    //1,2,3,4

        ==>解决js引用问题:
        将arr2定义为一个空数组,这时arr1与arr2指向不同的内存空间
         var arr1=[1,2,3];
         var arr2=[];
         for(var i=0;i<arr1.length;i++){
             arr2.push(arr[i]);
         }
         arr2.push(4);
         alert(arr1);    //1,2,3
         alert(arr2);    //1,2,3,4


    JS面向对象的继承:
    1.通过call让B继承A的属性
    2.通过B.prototype=A.prototype让B继承A的方法(会出现js引用问题)
      解决A,B之间引用问题--通过for-in循环
      for(var i in A.prototype){
            B.prototype[i]=A.prototype[i];
        }
    3.继承详解:
        function A(){
            this.abc=12;
        }
        A.prototype.show=function(){
            alert(this.abc);
        }
        //继承A
        function B(){
            //this-->new B
            A.call(this);    //本来给A添加属性,现在通过call改变A中的this,变成给B添加属性
        }
        B.prototype=A.prototype;    //继承A的方法,但会出现js引用问题,让A和B同时指向一个内存空间
        B.prototype.fn=function(){  //给子类B新添加属于自己独有的方法
            alert('dec');
        }
        var objB=new B();
        var objA=new A();
        alert(objB.abc);    //12
        objB.show();        //12
        objB.fn();    //dec
        objA.fn();    //dec,这时子类B对象上的方法同样出现在A对象上面,而A对象不应该有,出现问题,是因为js引用的问题

        //解决A,B之间引用问题-->通过for-in循环
        JS继承最终代码:

        function A(){
            this.abc=12;
        }
        A.prototype.show=function(){
            alert(this.abc);
        }
        //继承A
        function B(){
            //this-->new B
            A.call(this);    //本来给A添加属性,现在通过call改变A中的this,变成给B添加属性
        }
        //B.prototype=A.prototype;    //会出现js引用问题,让A和B同时指向一个内存空间
        for(var i in A.prototype){
            B.prototype[i]=A.prototype[i];
        }
      B.prototype.fn=function(){
            alert('abc');
        }
        var objB=new B();
        var objA=new A();
        alert(objB.abc);    //12
        objB.show();        //12
        objB.fn();    //abc
        //objA.fn();    --这时再写这句话就会报错,所以应该去掉,因为A没有fn这个方法才是正确的

     继承例子:
         继承父类的拖拽,实现子类有限制范围的拖拽

    <style media="screen">
        #parentDiv{
           350px;
          height: 350px;
          background: #ccc;
          position: relative;
        }
        #div1{
           150px;
          height: 150px;
          background: red;
          position: absolute;
        }
        #div2{
           100px;
          height: 100px;
          background: blue;
          position: absolute;
        }
      </style>
    
    
    <div id="parentDiv">
        <div id="div1">父类拖拽</div>
        <div id="div2">子类限制范围继承拖拽</div>
     </div>
    
    
    <script type="text/javascript">
        window.onload=function(){
          var dragDiv=new Drag('div1');
          var limitDrag=new LimitDrag('div2');
        }
        //父类面向对象的拖拽
        function Drag(id){
          var _this=this;
          this.disX=0;
          this.disY=0;
          this.oDiv=document.getElementById(id);
          this.oDiv.onmousedown=function(ev){
            _this.mouseDown(ev);
            return false;
          };
        }
        Drag.prototype.mouseDown=function(ev){
          var _this=this;
          var oEvent=ev||event;
          this.disX=oEvent.clientX-this.oDiv.offsetLeft;
          this.disY=oEvent.clientY-this.oDiv.offsetTop;
          document.onmousemove=function(ev){
            _this.mouseMove(ev);
            return false;   //阻止拖动过程中选中文字的默认行为
          };
          document.onmouseup=function(){
            _this.mouseUp();
          };
        }
    
        Drag.prototype.mouseMove=function(ev){
          var oEvent=ev||event;
          this.oDiv.style.left=oEvent.clientX-this.disX+'px';
          this.oDiv.style.top=oEvent.clientY-this.disY+'px';
        }
        Drag.prototype.mouseUp=function(){
          document.onmousemove=null;
          document.onmouseup=null;
        }
    
        //子类继承父类实现有限制范围的拖拽
        //1.继承父类的属性
        function LimitDrag(id){
          Drag.call(this,id);
        }
        //2.继承父类的方法
        for(var i in Drag.prototype){
          LimitDrag.prototype[i]=Drag.prototype[i];
        }
        //3.重写,将子类与父类不同的地方进行重写
        //(子类从父类那里已经继承一个mouseMove,这时重写将把原来的覆盖)
        LimitDrag.prototype.mouseMove=function(ev){
          var oEvent=ev||event;
          var parentDiv=document.getElementById('parentDiv');
          var l=oEvent.clientX-this.disX;
          var t=oEvent.clientY-this.disY;
          if (l<0) {
            l=0;
          }else if(l>parentDiv.offsetWidth-this.oDiv.offsetWidth){
            l=parentDiv.offsetWidth-this.oDiv.offsetWidth;
          }
          if (t<0) {
            t=0;
          }else if(t>parentDiv.offsetHeight-this.oDiv.offsetHeight){
            t=parentDiv.offsetHeight-this.oDiv.offsetHeight;
          }
          this.oDiv.style.left=l+'px';
          this.oDiv.style.top=t+'px';
        }
      </script>

    3.系统对象:(js里面的对象)
        1)本地对象(非静态对象)
            --需要经过实例化(new)的对象,才可以使用==>var arr=new Array();    arr.search();
            --常用对象:Object,Function,Array,String,Boolean,Number,Date,RegExp,Error
        2)内置对象(静态对象)
            --不需要经过实例化(new)的对象,直接可以使用==>Math.ceil();
            --常用:Global,Math
        3)宿主对象(由浏览器提供的对象)
            --对于JS的宿主,就是js的运行环境,一般指浏览器DOM,BOM
            --宿主对象随着js运行环境的不同而不同(而1,2与js运行环境无关),
            --如node中在后台编写代码,他就有新的js对象

  • 相关阅读:
    Android studio 搭建测试环境 创建虚拟机
    Halcon算子翻译——break
    Halcon算子翻译——throw
    halcon算子翻译——stop
    halcon算子翻译——return
    halcon算子翻译——par_join
    Halcon算子翻译——import
    Halcon算子翻译——global
    Halcon算子翻译——export_def
    Halcon算子翻译——exit
  • 原文地址:https://www.cnblogs.com/yufann/p/JS-Summary5.html
Copyright © 2020-2023  润新知