• JavaScript中的面向对象编程,详解原型对象及prototype,constructor,proto,内含面向对象编程详细案例(烟花案例)


    面向对象编程:
     
    面向:以什么为主,基于什么模式
    对象:由键值对组成,可以用来描述事物,存储数据的一种数据格式
    编程:使用代码解决需求
     
    面向过程编程:
            按照我们分析好的步骤,按步骤解决问题
            优点:性能比面向对象高,适合跟硬件联系很紧密的东西
            缺点:没有面向对象那么容易维护,复用,扩展
     
    面向对象编程:
            把事务分解成一个个对象,然后由对象之间分工与合作,分工明确,每一个对象都是功能中心
            面向对象特性:封装性、继承性 、多态性
                        封装性:将一个功能封装起来,小封装
                                        将多个函数封装起来,整体封装起来形成一个具体的对象
                        继承性:让一个不具有某些特性的对象,具有另一个对象的特征
     
                        多态性:多种形态,一个功能的不同应用场景
                                    应用场景,创建场景
     
            优点:灵活,代码可复用,容易维护和开发适合多人合作大型软件项目,可以设计出低耦合的系统使系统更加灵活、更加易于维护
            缺点:性能比面向过程 低
     
    OOP (Object Oriented,OO)面向对象编程
    OOA 面向对象分析:需求,拆分成各种各样的小需求,按照分工协作的形式
                不断的拆分,直到拆分成每一个步骤可以直接使用分工协作的方式解决
    OOD 面向对象设计:高内聚,低耦合
     
     
     
    1、创建对象
        单体对象
        var obj = {};
        var obj2 = new object();
     
        多个对象:
        人的对象具有自我节介绍的功能
        工厂模式:
     
      JS内置的工厂模式:
        function CreatPeople(name,age,like){
                this.name = name;
                this.age = age;
                this.like = like;
                this.show = function(){
                    alert("我叫"+this.name+",今年"+this.age+"岁,喜欢"+this.like);
                }
            }
            var obj = new CreatPe
    ople("ABC",20,"PHP");
            var obj2 = new CreatPeople("QWE",32,"Python");
            obj.show();
            obj2.show();
        JS内置的工厂模式比传统的工厂模式更高效,复用性更强。
     
        JS内置的工厂模式构造函数
     
    new的原理:
        1.创建一个新的空对象
        2.将这个对象的__proto__和函数的prototype做连接
        3.将这个函数中的this改变,指向new新创建的对象
        4.检测函数有没有返回对象,没有返回对象,就返回new创建的对象
     
     
     
    构造函数,构造自定义的函数,会在函数中使用this、找到被构造出来的对象
    隐患:一旦构造函数被直接执行,会错误的产生大量的全局变量
    解决隐患:解决不了
    自我约束:构造函数不要直接执行
    防止误操作:行业习惯:为了防止构造函数被直接执行,产生大量的全局变量,一般将需要被构造的函数的首字母大写
    以此标志构造函数和正常函数的区别
     
    function Fn(){
    this.name = "root";
    }
    var f = new Fn()
    console.log(f.name)
     
     
    console.log(name)
     
     
    this的指向问题
    默认绑定:window
    隐式绑定:执行对象
    显示绑定:函数的方法,强行绑定
    new绑定:将函数中的this指向了new出来的对象
     
    【构造函数】
      用来初始化新创建的对象的函数是构造函数。在例子中,Foo()函数是构造函数
    【实例对象】
      通过构造函数的new操作创建的对象是实例对象。可以用一个构造函数,构造多个实例对象
    function Foo(){};
    var f1 = new Foo;
    var f2 = new Foo;
    console.log(f1 === f2);//false
     
    【原型对象及prototype】
      构造函数有一个prototype属性,指向实例对象的原型对象。通过同一个构造函数实例化的多个对象具有相同的原型对象。经常使用原型对象来实现继承
    function Foo(){};
    Foo.prototype.a = 1;
    var f1 = new Foo;
    var f2 = new Foo;
     
    console.log(Foo.prototype.a);//1
    console.log(f1.a);//1
    console.log(f2.a);//1
     
    【constructor】
      原型对象有一个constructor属性,指向该原型对象对应的构造函数
    function Foo(){};
    console.log(Foo.prototype.constructor === Foo);//true
     
             由于实例对象可以继承原型对象的属性,所以实例对象也拥有constructor属性,同样指向原型对象对应的构造函数
     
    function Foo(){};
    var f1 = new Foo;
    console.log(f1.constructor === Foo);//true
    proto
      实例对象有一个proto属性,指向该实例对象对应的原型对象
    function Foo(){};
    var f1 = new Foo;
    console.log(f1.__proto__ === Foo.prototype);//true
     
    案例:
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <style>
            body{
                 100%;
                height: 100%;
                /* background: url(img/bg.jpg); */
                background-color: #000;
            }
            #container{
                 100%;
                height: 900px;
                cursor: pointer;
                position: relative;
                left: 0;
                top: 0;
                overflow: hidden;
            }
            .fire{
                 30px ;
                height: 30px;
                position:absolute  ;
                bottom: 0;
                background: url(img/0.jpg) no-repeat;
                border-radius: 50%;
                background-size: cover;
            }
            .small-fire{
                 100px;
                height: 100px;
                position: absolute;
                border-radius: 50%;
                background:url(img/500.gif) no-repeat;
                background-size: cover;
            }
        </style>
    </head>
     
     
    <body>
        <div id="container"></div>
    </body>
     
     
    <script src = "../move.js"> </script>
     
     
    <script src = "../public.js"> </script>
     
     
    <script>
    // OOA:分析
        // 烟花,点击出现烟花,运动到鼠标点击处炸开。运动到随机位置,删除
            // 实现步骤:
                // 1.创建主题烟花。设置样式,和初始位置
                // 2.开始运动,从底部上升到鼠标高度。运动结束
                // 3.删除主题烟花,创建随机烟花
                // 4.立即运动,到终点,删除小烟花
     
     
    // ood设计
        // function Fire(){
        //     // 创建主题烟花,设置样式,位置
        //     this.init()
        // }
        // Fire.prototype.init = function(){
        //     // 主题烟花,设置样式,和位置
        //         2.开始运动,运动结束
        //         this.animate()
        // }
        // Fire.prototype.animate = function(){
        //     开始运动,删除主体烟花
        //         3.创造小烟花
        //         this.createSmall()
        // }
        // Fire.prototype.createSmall = function (){
        //     // 创建小烟花,运动,删掉
        // }
     
     
        // ============================
            function Fire (options){             //接受传参
                this.x = options.x;          //这里把鼠标点击的横坐标赋值给this的x
                this.y = options.y;              //这里把鼠标点击纵坐标赋值给this的y
                this.cont = options.parent;      //这里把点击事件的this赋值给了cont
     
     
                    // 运行创建烟花的封装函数
                this.init();                     //运行下面创建主体烟花的函数运行
            }
            Fire.prototype.init = function(){        //创造主体烟花的函数
                //主题烟花的新建,样式,位置以及插入的设置
                this.ele = document.createElement("div");        //创建一个元素节点,一个div元素并设置名称为ele
                this.ele.className = "fire";                     //这里把类名为"fire"的class类赋值给新增加的div元素ele
                this.ele.style.left = this.x +"px";              //这里把烟花的定位left设置成鼠标点击x坐标,
                this.cont.appendChild(this.ele);                 //这里把新创建的div元素ele插入到cont里面
                this.animate();                                  //运行下一步,以回调函数的方式
            }    
            Fire.prototype.animate = function(){                 //创建一个 运动以及小烟花的函数
                //开始运动,这里运行运动的封装函数move,(里面包含获取样式的封装函数)
                move(this.ele,{                                  //move是之前封装的运动的函数,把插入的div元素和鼠标点击的y坐标赋给了的top,还有删除元素及运行下一个函数的回调函数,传给move,形成一个运动效果
                    top:this.y
                },function(){
                    //主体烟花出现后,删除这个主体烟花,并创建小烟花
                    this.ele.remove();
                    this.createSmall()
                }.bind(this))   //这里的bind是找回this
     
     
            }
            Fire.prototype.createSmall = function(){                 //创建小烟花和删除小烟花函数
                //创建小烟花,运动,然后删除
                var num = random(10,20);    //这里是创建小烟花的个数的随机数
                var r = random(100,500)
                // console.log(num);
                for(var i=0;i<num;i++){                               //循环遍历每一个小烟花,给他设置样式以及位置
                    let div = document.createElement("div");             //创建新的div
                    div.className ="small-fire";                         //赋予样式
                    div.style.left = this.x +"px";                       //设置定位的left为鼠标的x坐标
                    div.style.top = this.y +"px";                        //设置定位的top为鼠标点击的坐标
                    div.setAttribute("i",i)   //这里i的作用为给新生成的div一个编号,后期删除的效果会比较好
                    this.cont.appendChild(div);                  //在cont插入新创建的div
                    
                    //生成烟花位置的随机数的坐标
                    // var l = random(0,this.cont.offsetWidth - div.offsetWidth);       //烟花位置的l为从到cont的宽度和高度减去新创建的小烟花的高宽之间的随机数
                    // var t = random(0,this.cont.offsetHeight - div.offsetHeight);
                    // console.log(cont);
                    var l = parseInt(Math.cos(Math.PI/180*(360/num*i))*r)+this.x;
                    var t = parseInt(Math.sin(Math.PI/180*(360/num*i))*r)+this.y;
                    
                    move(div,{                                //move,生成运动传入元素div和位置(定位信息)
                        left:l,              
                        top:t
                    },function(){
                        div.remove()                     //随即把插入的div删除
                    })
                }
     
     
                
     
     
              }
     
     
     
     
     
     
            var ocont = document.getElementById("container");            //获取div元素
            ocont.onclick = function(eve){                               //设置点击事件,点击div产生事件
                var e = eve ||window.event;                          //事件兼容以及获取事件
                new Fire({                                           //构造一个面向对象的函数,并传参
                    x:e.offsetX,                                        //把鼠标点击的横坐标赋值给x
                    y:e.offsetY,                                 //把鼠标点击的纵坐标赋值给y
                    parent:this                                  //把点击事件的this赋值给parent
                });
            }
     
     
     

     

  • 相关阅读:
    StackView
    横竖屏
    Html
    UILabel
    NSString
    NSPredicate|谓词
    iphone
    函数
    UIBezierPath
    UICollectionView
  • 原文地址:https://www.cnblogs.com/zxlone/p/11518782.html
Copyright © 2020-2023  润新知