JS面向对象程序设计

什么是面向对象?

面向对象是相对于面向过程来讲的,面向对象方法,把相关的数据和方法组织为一个整体来看待,从更高的层次来进行系统建模,更贴近事物的自然运行模式。

面向过程是分步执行

在这里插入图片描述

面向对象是关注整体,按模块执行

在这里插入图片描述

创建对象

字面量创建

// 创建对象
        var obj = {
            // 添加属性
            name : "xiaoming",
            age : "12",
            // 添加方法
            introduction : function(){
                console.log( "我是" + this.name);
            }
        }
        // 调用方法
        obj.introduction();

内置构造函数

   // 创建对象
    var obj = new Object();
    // 添加属性
    obj.name = "xiaoming";
    obj.age = "12";
    // 添加方法
    obj.introduction = function(){
          console.log( "我是" + this.name);
    }
    // 调用方法
    obj.introduction();

工厂函数构造对象

// 构造函数
function creatObject( name , age ){
    
    var obj = new Object();
    // 原料
    obj.name = name;
    obj.age = age;
    // 加工
    obj.introduction = function(){
            console.log( "我是" + this.name + "今年" + this.age );
    }
    // 出厂
    return obj;
}
// 创建对象
var student1 = creatObject( "xiaoming" , 33)
var student2 = creatObject( "xiaohong" , 23)
// 调用方法
student1.introduction();
student2.introduction();

构造函数创建

 //构造函数创建的对象;
    // 构造函数
    function creatObject( name , age ){
        
        this.name = name; //把数据存入对象中
        this.age = age;

        // 创建方法
        this.introduction = function(){
            console.log( "我是" + this.name + "今年" + this.age );
            console.log(this)
            // this指向的是当前对象
        }
        // 函数内调用
        this.introduction();
    }
    // 创建对象
    var student1 = new creatObject( "xiaoming" , 33)
    // 在这里用new创建函数中可以省去new Object()
    var student2 = new creatObject( "xiaohong" , 23)

原型对象prototype

   // 构造函数
    function creatObject( name , age ){
        
        this.name = name; //把数据存入对象中
        this.age = age;
        // 调用方法
        this.introduction();
    }
    // 创建方法
    creatObject.prototype.introduction = function(){
        console.log( "我是" + this.name + "今年" + this.age );
        console.log(this)
        // this指向的是当前对象
    }
    // 创建对象
    var student1 = new creatObject( "xiaoming" , 33)
    // 在这里用new创建函数中可以省去new Object()
    var student2 = new creatObject( "xiaohong" , 23)

原型方法简化

当函数功能较多时可以将原来的原型对象编成我们的对象

  // 构造函数
    function creatObject( name , age ){
        
        this.name = name; //把数据存入对象中
        this.age = age;
        // 调用方法
        this.showName();
        this.showAge();
    }
    // 创建方法
    creatObject.prototype = {
        // 赋值之后 constructor 没有了,需要我们手动填写
        constructor : creatObject,
        showName : function(){
            console.log( "我是" + this.name);
            console.log(constructor)
        },
        showAge : function(){
            console.log( "今年" + this.age );
        }
    }
    // 创建对象
    var student1 = new creatObject( "xiaoming" , 33)
    // 在这里用new创建函数中可以省去new Object()
    var student2 = new creatObject( "xiaohong" , 23)

面向对象案例(萤火虫效果)

面向对象编程分为三个阶段 OOA(面向对象分析)、OOD(面向对象设计)、OOP(面向对象编程)

OOA

  1. 创建元素.放入页面;
  2. 设置随机位置; 有边界的;
  3. 设置随机的目标;
  4. 运动;
  5. 运动结束之后,需要重新设置随机目标,重新进行运动…

OOD

  function Glowworm(){
        }
        Glowworm.prototype = {
              constructor : Glowworm,
              init  : function(){
                    // 所有的耦合关系都在这里;
                    // 创建元素;
                    // 放入页面有一个随机位置;
                    // 运动;
              },
              // 创建元素
              createGlowwormEle : function(){
              },
              // 设置边界
              glowwormBoundary : function(){                      
              },
              // 运动目标
              glowwormTarget   : function(){
              },
              // 运动
              glowwormAnimate : function(){                        
              }
        }

OOP

 function Glowworm( selector ){
        this.container = document.querySelector(selector);
        // 获取父元素放入当前对象的container中
        this.init();
        // 调用init方法;
  }
  Glowworm.prototype = {
        constructor : Glowworm,
        init  : function(){
              // 调用创建方法来创建萤火虫
              this.ele = this.createGlowwormEle();
              // 让萤火虫出现的位置是随机的; 
              // 1. 获取随机位置;
              var boundary = this.glowwormBoundary();
              // 2. 将随机位置赋值给萤火虫;
              this.ele.style.left = boundary.left + "px";
              this.ele.style.top  = boundary.top + "px";
              // 让萤火虫随机移动; 需要一个运动的目标点;
              // 运动需要实现的复杂功能;

              animate(this.ele , this.glowwormBoundary() , function(){
              animate(this.ele , this.glowwormBoundary() , arguments.callee.bind(this) );
                    // callee指向当前匿名函数
              }.bind(this));
              // 封装中的animate this会指向window,需要用bind来更改指向
        },
        createGlowwormEle : function(){
              var ele = document.createElement("div")
              ele.className = "fire-bug";
              this.container.appendChild(ele);
              return ele;
        },
        glowwormBoundary : function(){
              // min 0 max 容器的宽度 - 元素的宽度;
              var left_max = this.container.offsetWidth  - this.ele.offsetWidth;
              var top_max  = this.container.offsetHeight - this.ele.offsetHeight;
              return {
                    left : parseInt(left_max * Math.random() + 1),
                    top  : parseInt(top_max  * Math.random() + 1),
              }
              
        },
        glowwormAnimate : function(){
              
        }
  }
  for(var i = 0 ; i < 20 ; i ++){
        new Glowworm("#container");
        //重复调用20次
  }
  </script>

animate为封装的方法

function animate( ele , attr_options , callback ){    
    // 1. 获取元素当前的属性;
    // 因为数据增加,所以重新建立 attr_options结构;
    // console.log(attr_options);
    for(var attr in attr_options){
        // 我们需要记录的数据有 : 属性名 : 目标点, 当前元素的属性;
        // { "width" : {
        //         target : 200 ,
        //         iNow   : 元素的属性值;
        //     } 
        // }
        // attr : width : height;
        attr_options[attr] = {
            //  目标点 : 传入的数据;
            target : attr_options[attr],
            //  元素当前的属性值 ;
            iNow   : parseInt( getComputedStyle(ele)[attr] )
        }
        // console.log(attr_options[attr])
    }
    // 关闭开启定时器;
    clearInterval( ele.timer );
    ele.timer = setInterval( function(){
        // 1. 获取速度; width :  height : 
        for(var attr in attr_options){
            // attr : width | height;
            var item = attr_options[attr];
            // console.log(item , attr);
            var target = item.target;
            var iNow   = item.iNow;
            // 运动所必须的值我们都有了;
            // 计算速度;
            var speed = (target - iNow) / 10;
            // 速度取整;
            speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);

            // 终止条件 : 
            if( Math.abs( target - iNow) <= Math.abs(speed) ){
                // 终止定时器 ; 
                // 送他一把;
                // clearInterval( ele.timer );
                // ele.style[attr] = target + "px";
                // 终止条件不可靠,因为目标的不一致会让运动次数执行不同,有可能提前关闭定时器;
                ele.style[attr] = target + "px";
                // 一条运动完成删除对象里面的数据;
                delete attr_options[attr];
                // 如果对象里面没有属性了,那么我们关闭定时器就可以了;
                for(var num in attr_options){
                    // 如果attr_options里面有属性,那么此时我就不应该终止定时器;
                    return false;
                }
                clearInterval(ele.timer);
                typeof callback === "function" ? callback() : "";
            }else{
                // 元素运动;
                // 因为 iNow 是一个临时变量,所以不能再去操作iNow , 要去操作iNow 的数据源;
                // 多花点经历理解这段代码;
                attr_options[attr].iNow += speed;
                ele.style[attr] = attr_options[attr].iNow + "px";
            }
        }
    } , 30)
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值