javascript 知识点 第十一篇 面向对象

169 阅读17分钟

十一 面向对象

一 构造函数

  • 构造函数与普通函数的区别
    普通函数如果内部没有return的时候 返回的是undefined
    构造函数内部没有return返回值的时候,返回的构造出来的对象。
    
    普通函数内部的this指向,指向的是window
    构造函数内部的this指向,指向的是当前对象。
    
    总结:构造函数在new的时候构建对象,会在内部自动返回一个this  指向构造的对象
    
     注:   为了区分构造函数与普通函数:  构造函数的首字母 大写!!!!!
    
    //构造函数与普通函数的区别
    
    //普通函数没有return 调用时 返回值 为undefind
        //普通函数调用 fn()
        function fn(){
    
        }
        console.log(fn());
    
    //构造函数调用时,没有return  返回值是构造出来的对象(fn{})
        //构造函数调用new fn();
        function fn(){
    
        }
        console.log( new fn());
    
    //普通函数的this 指向 window
        function fn(){
            console.log(this);
        }
        fn();
    //构造函数的this 指向 当前对象
        function fn(){
                console.log(this);
            }
        new fn();
    
  • 构造函数与对象关系
 对象是构造函数构建出来的, 对象用来存储数据;
        构造函数 ----(new)---- 对象 ----- (存储) ----  数据
        
 通过new 调用的就是构造函数,
 new 出来的是 对象

二 面向对象

1.面向对象的特点
面向对象的特点:
    封装
    继承
    多态
    抽象: 抽取一个功能里面的多个核心的功能模块

    js里面面向对象: 封装 继承 抽象

思想: 高内聚  低耦合
    低耦合:每个功能模块之间耦合度要低
    高内聚:模块内部要紧密相连
    

面向对象的风格都是从 new 开始的!!
    var str = new String();
    var reg = new RegExp();
    var arr = new Array();
    var d = new Date();
    var obj = new Object();
    var fn = new Function()
    var num = new Number();
拓展:
    面向过程:
            1.顺序结构,里面的步骤和顺序 不能随意颠倒
            2.形成大量全局变量,造成变量污染

    js对象的分类:
        宿主对象、内置对象 (Math)、内部对象( new
2.工厂模式
function fn(){
    var obj = new Obeject()
    obj.name = '';
    retrun obj;
}
//打印出对象内部的属性和方法
    console.dir(Array);

    //需求:用对象保存一辆车
    var car1 = new Object();
    car1.name = '奥迪';
    car1.volume = '4.0T';
    car1.type = 'suv';
    console.log(car1);
    //需求:保存100辆车  封装一个方法
//工厂模式
    function car(name,volume,type){
        var obj = new Object();  //工厂
        obj.name = name;         //加工
        obj.volume = volume;
        obj.type = type;
        return obj ; //普通函数要有返回值
    }
    //调用方法
    var car1 = car('奥迪','4.0T','suv');
    var car2 = car('奥拓','1.0T','suv');
    var car3 = car('奔驰','3.0T','suv');
    console.log(car1,car2,car3);

//每一次调用都要new一个对象
3.面向对象的风格new
//工厂模式的加工 --- 把new提取出来

function Car(name, volume, type) {
            this.name = name;         //加工
            this.volume = volume;
            this.type = type;
            this.fn = function () {
                console.log(this.name);// this 指向这个对象 fn{} == Car
            }
        }
        //调用方法
        var car1 = new Car('奥迪', '4.0T', 'suv');
        var car2 = new Car('奥拓', '1.0T', 'suv');
        var car3 = new Car('奔驰', '3.0T', 'suv');
        // console.log(car1, car2, car3);

        car1.fn(); //== car1.name  奥迪
        car2.fn();
        car3.fn();
    //注意:此时的car1.fn == car2.fn 为false
        console.log(car1.fn == car2.fn);//false

        var arr1 = new Array();
        var arr2 = new Array();
        console.log(arr1.push == arr2.push);

        console.dir(Array);
        console.dir(Object);
        console.dir(String);
       
    </script>
4.实例化多个对象时,构造函数的方法是否一致
 function Car(name, volume, type) {
            this.name = name;         //加工
            this.volume = volume;
            this.type = type;
            this.fn = function () {
                console.log(this.name);// this 指向这个对象 fn{} == Car
            }
        }
        //调用方法
        var car1 = new Car('奥迪', '4.0T', 'suv');
        var car2 = new Car('奥拓', '1.0T', 'suv');
        var car3 = new Car('奔驰', '3.0T', 'suv');
        // console.log(car1, car2, car3);

        car1.fn(); //== car1.name  奥迪
        car2.fn();
        car3.fn();
    //测试car1 的fn 方法 和 car2 的 fn 方法是否为同一方法 ?
        console.log(car1.fn == car2.fn);//false

/*
1、在内存中开辟了一块(new一次就开辟了一个空间)
2、把this的指向指向了它
***每一次new的时候都会开辟一块内存,所以不相等。
*/

        var arr1 = new Array();
        var arr2 = new Array();
        console.log(arr1.push == arr2.push);  //true
//疑问:  为什么Array 的push 方法是一致的 
    
4.prototype
prototype  指向 当前对象 原型对象!!!
/*
    每一个函数都会存在一个原型对象 prototype
    存放着公共的属性和方法。
    
     总结prototype的作用:
        1: 存储公共的属性和方法
        2:减少内存开销
        3:扩展属性和方法
        4:实现继承!!!!!!
*/
function Car(name,type){
          this.name = name;
          this.type = type;
      }
    //   Car.prototype.printName = function(){
    //       console.log(this.name);
    //   }
    //   Car.prototype.printType = function(){
    //       console.log(this.type);
    //   }
//以对象的方式进行添加到prototype属性中(此方法是Car 对象的公共属性和方法)
    Car.prototype = {
        printName: function(){
            console.log(this.name)
        },
        printType: function(){
            console.log(this.type)
        },
    }
      var car1 = new Car('1','22');
      var car2 = new Car('a','bbb');
      console.log(car1,car2);
      console.dir(Car);
      console.log(car1.printName == car2.printName);//true

//给数组添加去重的公共方法

var arr = [1,4,5,3,5,2,3,2,2,3,2];
    Array.prototype.norepeat = function(){
        var arrTemp = [];
        for(let i = 0; k = this.length, i < k; i++){
            if(arrTemp.indexOf(this[i]) == -1){
                arrTemp.push(this[i]);
            }
        }
        return arrTemp;
    }
    console.log(arr.norepeat());

三 面向对象的实现流程

面向对象实现流程:
    1:把全局的变量做为属性
    2: 把对象的方法放在prototype
    3: new实例化对象。
    4this指向!!!

function 构造函数名称首字母大写(){
            //属性
            this.属性名称1 = '属性值1';
            this.属性名称2 = '属性值2';
            this.属性名称3 = '属性值3';

            //调用初始化方法
            this.init();
        }
        构造函数名称首字母大写.prototype = {
            //方法放在prototype对象上
            //方法:实现效果的 多个功能模块

            //初始化方法  : 整合各个功能模块
            init : function(){
                
            },
            //各个功能模块
            fn1 : function(){

            },
            fn2 : function(){

            },
            fn3 : function(){

            },
            //绑定事件模块
            evnetBind : function(){

            }
        }
        new 构造函数名称首字母大写();

四 面向对象案例

1.面向对象实现轮播图
<!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>
        * {
            margin: 0;
            padding: 0;
        }

        section {
            height: 350px;
            width: 1000px;
            background: orange;
            margin: 30px auto;
            position: relative;
        }

        section span {
            display: block;
            height: 50px;
            width: 50px;
            border-radius: 50%;
            background: rgba(200, 0, 0, 0.8);
            position: absolute;
            top: 150px;
            font-size: 30px;
            line-height: 50px;
            text-align: center;
            font-weight: bold;
            color: #fff;
            z-index: 1;
            cursor: pointer;

        }

        section span:nth-of-type(1) {
            left: 20px;
        }

        section span:nth-of-type(2) {
            right: 20px;
        }

        .imgBox {
            height: 350px;
            position: absolute;
        }

        .imgBox img {
            height: 350px;
            width: 1000px;
            float: left;
        }
    </style>
</head>

<body>
    <section>
        <div class="imgBox">
            <img src="./img/1.jpg" alt="">
            <img src="./img/2.jpg" alt="">
            <img src="./img/3.jpg" alt="">
            <img src="./img/4.jpg" alt="">
            <img src="./img/5.jpg" alt="">
        </div>
        <span>
            <</span> <span>>
        </span>
        <script src="../../myAPi/myApi.js/move.js"></script>
        <script src="../../myAPi/myApi.js/myAPI.js"></script>
        <script>
          
            /*  面向对象实现轮播图  */

            /*
                功能模块拆分:
                    1.图片移动
                    2.上一张
                    3.下一张
                    4.事件绑定模块
            */
            function Banner() {
                //存储属性
                this.oImgBox = document.querySelector('.imgBox');
                this.aImg = document.getElementsByTagName('img');
                this.distance = this.aImg[0].offsetWidth;
                this.aBtn = document.getElementsByTagName('span');
                this.count = 0;

                this.init();
            }

            Banner.prototype = {
                //初始化方法
                init: function() {
                    this.oImgBox.style.width = this.aImg.length * this.distance + 'px';
                    this.eventBind();
                },
                toImg: function() {
                    move(this.oImgBox, { 'left': -this.distance * this.count });
                },
                next: function() {
                    if (this.count >= this.aImg.length - 1) {
                        this.count = 0;
                    } else {
                        this.count++;
                    }
                    this.toImg();
                },
                pre: function() {
                    if (this.count <= 0) {
                        this.count = this.aImg.length - 1;
                    } else {
                        this.count--;
                    }
                    this.toImg();
                },
                eventBind: function() {
                    addEventListener(this.aBtn[1], 'click', this.next.bind(this));
                    addEventListener(this.aBtn[0], 'click', this.pre.bind(this));
                },
            }
            new Banner();
        </script>
    </section>
</body>

</html>
2.面向对象实现选项卡
<!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>
    *{
        margin:0;
        padding:0;
    }
    div{
        height:40px;
        width:300px;
        background:#ccc;
        margin:30px auto 0;
    }
    div span{
        height:40px;
        width:98px;
        background:yellow;
        margin-right:2px;
        float:left;
        font-size:30px;
        font-weight:900;
        color:#fff;
        line-height:40px;
        text-align:center;
        cursor: pointer;
    }
    .active{
        background:blue;
        color:black;
    }
    section{
        height:300px;
        width:300px;
        margin:0 auto;
        position:relative;
        background:#fff;
    }
    article{
        height:300px;
        width:300px;
        background:orange;
        position:absolute;
        text-align:center;
        font-size:30px;
        line-height:300px;
        display:none;
    }
    .show{
        display:block;
    }
    </style>
</head>
<body>
    <div>
        <span class='active'>TAB1</span>
        <span>TAB2</span>
        <span>TAB3</span>
    </div>
    <section>
        <article class = 'show'>内容1</article>
        <article>内容2</article>
        <article>内容3</article>
    </section>
    <script>
    /*
        功能分析:
            1.清除所有类名
            2.添加所有类名
            3.下标
            4.鼠标点击切换内容
    */
   function Tab(){
       this.aBtn = document.querySelectorAll('span');
       this.article = document.querySelectorAll('article');
       this.init(); 
   }

   Tab.prototype = {
       //初始化方法
       init:function(){
            this.eventBind();
       },
       //清除类名
       clearClass:function(){
           //循环遍历
           for(let i = 0, k = this.aBtn.length; i < k; i++){
               this.aBtn[i].className = '';
               this.article[i].className = '';
           }
       },
       //添加类名
       addClass:function(index){
           //在添加类型之前先清除类名
           this.clearClass();
           this.aBtn[index].className = 'active';
           this.article[index].className = 'show'
       },
       //事件绑定
       eventBind:function(){
            //循环遍历,鼠标滑过绑定事件
            for(let i = 0, k = this.aBtn.length;i < k; i++){
                this.aBtn[i].addEventListener('click',this.addClass.bind(this,i));
                //this.addClass.bind(this,i)  i 是addClass 里面的实参index;
            }
       },
   }
   new Tab();
    
    </script>
</body>
</html>
3.面向对象实现随机点名
<!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>
    *{
        margin:0;
        padding:0;
    }
    .box{
        height:40px;
        width:200px;
        background:orange;
        margin:100px auto 30px;
        font-size:30px;
        font-weight:bold;
        line-height:40px;
        text-align:center;
        color:#fff;
    }
    .btn{
        height:30px;
        width:100px;
        margin: 0 auto;
        background:black;
        font-size:20px;
        line-height:30px;
        text-align: center;
        color:#fff;
        cursor: pointer;
    }
    </style>
</head>
<body>
    <div class="box">随机点名</div>
    <div class="btn">开始</div>
    <script src="../../myAPi/myApi.js/myAPI.js"></script>
    <script>
    /*
        功能分解:
            1.随机切换文本
            2.开始
            3.暂停
            4.绑定点击事件
            
    */
   var arr = ['小明','小红','小苏','小孙','小刘','小李','小张']
   function RandomName(){
        this.box = document.querySelector('.box');
        this.btn = document.querySelector('.btn');
        this.flag = false;
        this.init();
   }
   RandomName.prototype = {
       //初始化入口
       init:function(){
            this.eventBind();
       },
       textChange:function(){
           var _this = this;//定时器中的this 指向window 需要保存this指向
           //清除定时器(防止越点越快)
           clearInterval(_this.timer);//timer 成为对象的一个属性,也可以吧timer添加在属性上
           _this.timer = setInterval(function(){
            //每个一段时间,随机产生下标,通过下标改变数组中的名字
            let num = parseInt(Math.random()*arr.length);
            _this.box.innerHTML = arr[num];
            _this.box.style.color = randomColor();
           },100) 
       },
       //开始
       startTxt:function(){
           this.btn.innerHTML = '开始';
       },
       //暂停
       stopTxt:function(){
            this.btn.innerHTML = '暂停';
       },
       //判断是否开始
       isStart:function(){
           if(this.flag){
               //点击开始,文本开始随机
                this.textChange();
                //按钮btn  显示 暂停
                this.stopTxt();
           }else{
               clearInterval(this.timer);
               this.startTxt();
           }
       },
       //控制flag
       controlFlag:function(){
           //
           this.flag = this.flag ? false : true;
           //控制flag 来控制开始和暂停
           this.isStart();
       },
       //事件绑定
       eventBind:function(){
           //当点击开始时, controlFlag 进行执行
           addEventListener(this.btn,'click',this.controlFlag.bind(this));
       }
   }
   new RandomName();
   /*
    执行逻辑:
        1.点击开始 - 执行口令(controlFlag)(flag = false) -- 改变flag 值 为true
        2.
   
   */
    </script>
</body>
</html>
4.面向对象实现拖拽
<!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>
    *{
        margin:0;
        padding:0;
    }
    .box{
        height:100px;
        width:100px;
        background:orange;
        position:absolute;
    }
    </style>
</head>
<body>
    <div class="box"></div>
    <script src="../../myAPi/myApi.js/myAPI.js"></script>
    <script>
    function Drag(){
        this.box = document.querySelector('.box');
        this.fn = null;
        this.init();
    }
    Drag.prototype = {
        //初始化对象
        init : function(){
            this.evnetBlind();
        },
        //鼠标按下
        handleDown:function(e){
            e = e || window.event;
            //鼠标按下获取鼠标 在div 中的位置
            // let x = e.offsetX, y = e.offsetY;
            //将x y 定义为Drag 中的两个属性
            this.x = e.offsetX;
            this.y = e.offsetY;
            //鼠标移动事件
            addEventListener(document,'mousemove',this.fn = this.handleMove.bind(this));
            //当鼠标抬起
            addEventListener(document,'mouseup',this.handleUp.bind(this));
        },
        //鼠标移动
        handleMove:function(e){
            e = e || window.event;
            //获取鼠标的位置
            let 
                l = e.clientX - this.x,
                t = e.clientY - this.y;
                //元素的位置
                this.box.style.left = l +'px';
                this.box.style.top = t + 'px';
        },
        //当鼠标抬起
        handleUp:function(){
            //移除事件监听(鼠标抬起移除鼠标移动事件)
            //removeEventListener 规定:移除事件监听 必须要和绑定的函数一致
            document.removeEventListener('mousemove',this.fn);
        },
        //事件绑定
        evnetBlind:function(){
            //当鼠标按下时调用按下事件
            addEventListener(this.box,'mousedown',this.handleDown.bind(this));
        }
    }
    new Drag();
    </script>
</body>
</html>
5.面向对象实现无缝轮播
<!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>
        * {
            margin: 0;
            padding: 0;
        }

        ul,
        ol,
        li {
            list-style: none;
        }

        section {
            height: 350px;
            width: 1000px;
            margin: 20px auto;
            background: orange;
            position: relative;
        }

        span {
            height: 40px;
            width: 40px;
            border-radius: 50%;
            background: rgba(0, 0, 200, 0.6);
            font-size: 30px;
            font-weight: bold;
            line-height: 40px;
            text-align: center;
            color: #fff;
            position: absolute;
            top: 155px;
            cursor: pointer;
        }

        span:nth-of-type(1) {
            left: 20px;
        }

        span:nth-of-type(2) {
            right: 20px;
        }

        .imgBox {
            height: 350px;
            position: absolute;
        }

        .imgBox img {
            height: 350px;
            width: 1000px;
            float: left;
        }

        .circleBox {
            height: 30px;
            width: 1000px;
            /* background:orange; */
            position: absolute;
            bottom: 20px;
            display: flex;
            justify-content: center;
            align-items: center;
        }

        .circleBox li {
            height: 20px;
            width: 20px;
            border-radius: 50%;
            background: #fff;
            margin-right: 5px;
            cursor: pointer;
        }

        .circleBox .active {
            background: blue;
        }
    </style>
</head>

<body>
    <section>
        <div class="imgBox">
            <img src="./img/1.jpg" alt="">
            <img src="./img/2.jpg" alt="">
            <img src="./img/3.jpg" alt="">
            <img src="./img/4.jpg" alt="">
            <img src="./img/5.jpg" alt="">
        </div>
        <span><</span>
        <span>></span> 
        <ol class="circleBox">
            <!-- <li class='active'></li>
            <li></li> -->
        </ol>
    </section>
    <script src="../../myAPi/myApi.js/move.js"></script>
    <script src="../../myAPi/myApi.js/myAPI.js"></script>
    <script>
        function Banner() {
            this.oS = document.querySelector('section');
            this.oImgBox = document.querySelector('.imgBox');
            this.aImg = document.getElementsByTagName('img');
            this.oCircleBox = document.querySelector('.circleBox');
            this.distance = this.aImg[0].offsetWidth;
            this.aBtn = document.querySelectorAll('span');
            this.count = 0;
            this.time = null;
            this.init();
        }
        Banner.prototype = {
            init: function () {
                this.clone();
                this.oImgBox.style.width = this.aImg.length * this.distance + 'px';
                this.create();
                this.eventBind();
            },
            //克隆第一张
            clone: function () {
                this.firstImg = this.aImg[0].cloneNode();
                this.oImgBox.appendChild(this.firstImg);
            },
            //动态添加圆点
            create: function () {
                for (var i = 0, k = this.aImg.length - 1; i < k; i++) {
                    this.createLi = document.createElement('li');
                    this.oCircleBox.appendChild(this.createLi);
                }
                //获取第一个圆点,并添加背景
                this.oCir = document.getElementsByTagName('li');
                this.oCir[0].className = 'active';
            },
            //图片移动
            toImg : function(){
                move(this.oImgBox,{'left' : - this.distance * this.count});
            },
            //下一张
            next : function(){
                if( this.count >= this.aImg.length - 1 ){
                    this.oImgBox.style.left = 0;
                    this.count = 1;
                }else{
                    this.count++;
                }
                this.toImg();
                this.clearActive();
                this.oCir[this.count >= this.aImg.length - 1 ? 0 : this.count].className = 'active';
            },
            pre : function(){
                if(this.count <= 0){
                    this.oImgBox.style.left = (this.aImg.length - 1) * (-this.distance) + 'px';
                    this.count = this.aImg.length - 2;
                }else{
                    this.count--;
                }
                this.toImg();
                this.clearActive();
                this.oCir[this.count].className = 'active';
            },
            //定时器
            autoPlay :function(){
                this.timer = setInterval(()=>{
                    //箭头函数的this 指向,谁调用指向谁,所以不用改变
                    this.next();
                },3000)
            },
            //清除定时器
            clearTimer :function(){
                clearInterval(this.timer);
            },
            //清除类名
            clearActive : function(){
                for(var i = 0, k = this.aImg.length - 1; i < k ; i++){
                    this.oCir[i].className = '';
                }
            },
            circle:function(){
                for(let i = 0; i < this.oCir.length;i++){
                    addEventListener(this.oCir[i],'mouseover',()=>{
                        this.clearActive();
                        this.oCir[i].className = 'active';
                        this.count = i;
                        this.toImg();
                    },30)
                }
            },
            //事件绑定
            eventBind:function(){
                addEventListener(this.aBtn[1],'click',this.next.bind(this));
                addEventListener(this.aBtn[0],'click',this.pre.bind(this));
                addEventListener(this.oS,'mouseover',this.clearTimer.bind(this));
                addEventListener(this.oS,'mouseout',this.autoPlay.bind(this));
                this.circle();
            }

        }
        new Banner();
    </script>
</body>

</html>
6.Tom猫
<!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>
    *{
        margin:0;
        padding:0;
    }
    img{
        display:block;
    }
    body{
        height:100%;
    }
    section{
        height:100%;
        width:100%;
    }
    #imgShow{
        height:100%;
        width:100%;
    }
    .cymbal{
        height:60px;
        width:60px;
        position:absolute;
        left:6%;
        bottom:45%;
    }
    .drink{
        height:60px;
        width:60px;
        position:absolute;
        left:6%;
        bottom:35%;
    }
    .eat{
        height:60px;
        width:60px;
        position:absolute;
        left:6%;
        bottom:25%;
    }
    .fart{
        height:60px;
        width:60px;
        position:absolute;
        right:6%;
        bottom:45%;
    }
    .pie{
        height:60px;
        width:60px;
        position:absolute;
        right:6%;
        bottom:35%;
    }
    .scratch{
        height:60px;
        width:60px;
        position:absolute;
        right:6%;
        bottom:25%;
    }
    
    </style>
</head>
<body>
    <section>
        <img src="./tom/img/Animations/angry/angry_00.jpg" alt="" id="imgShow">
    </section>
    <div class="cymbal">
        <img src="./tom/img/Buttons/cymbal/cymbal.png" alt="">
    </div>
    <div class="drink">
        <img src="./tom/img/Buttons/drink/drink.png" alt="">
    </div>
    <div class="eat">
        <img src="./tom/img/Buttons/eat/eat.png" alt="">
    </div>
    <div class="fart">
        <img src="./tom/img/Buttons/fart/fart.png" alt="">
    </div>
    <div class="pie">
        <img src="./tom/img/Buttons/pie/pie.png" alt="">
    </div>
    <div class="scratch">
        <img src="./tom/img/Buttons/scratch/scratch.png" alt="">
    </div>
    div.class

    <audio src="" id="music"></audio>
    <script>
    
    function Tom(){
        this.imgShow = document.getElementById('imgShow');
        this.btn = document.querySelectorAll('div');
        this.music = document.getElementById('music');
        
        this.init(); 
    }
    Tom.prototype = {
        init:function(){
            this.eventBind();
            // this.tomplay('drink',80);
        },
        //切换图片
        tomplay:function(name,num){
            //30毫秒切换多张图片
            var _this = this;
            this.count = 0;//保证每次点击都从0 开始
            //开启定时器之前先要清除定时器(防止越点越快)
            clearInterval(this.timer);
            this.timer = setInterval(()=>{
                //需要进行判断,多少张暂停
                if(_this.count >= num){
                    //定时器中this需要保存
                    clearInterval(this.timer)
                    _this.count = 0;//清除count,否则count 一致保持在80
                }else{
                    _this.count++;
                    _this.imgShow.src = './tom/img/Animations/'+ name +'/'+ name  +'_'+ _this.mendZero(_this.count) +'.jpg'
                }
                
            },80)
        },
        //补零
        mendZero:function(num){
            if(num < 10){
                return '0' + num;
            }else{
                return num;
            }
        },
        //事件绑定
        eventBind:function(){
            //给集合绑定事件
            var _this = this;
            for(let i = 0,k = this.btn.length; i < k; i++ ){
                console.log(this);
                //绑定点击事件
                this.btn[i].onclick = function(){
                     //获取点击元素的类名
                     let classN = this.className;
                     //对类名进行判断
                     switch(classN){
                        case 'cymbal':
                        _this.tomplay('cymbal',12);
                        _this.music.src = './tom/mp3/pia.mp3';
                        _this.music.play();
                        break;
                        case 'drink':
                        _this.tomplay('drink',80);
                        break;
                        case 'eat':
                        _this.tomplay('eat',39);
                        break;
                        case 'fart':
                        _this.tomplay('fart',27);
                        break;
                        case 'pie':
                        _this.tomplay('pie',23);
                        break;
                        case 'scratch':
                        _this.tomplay('scratch',55);
                        break;
                     }
                }
            }
        }
    }
    new Tom();
    
    </script>
</body>
</html>
7.面向对象实现放大镜
<!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>
        * {
            margin: 0;
            padding: 0;
        }

        img {
            display: block;
        }

        .showBox {
            height: 530px;
            width: 430px;
            background: orange;
            margin: 50px 0 0 200px;

        }

        .productImg {
            height: 430px;
            width: 430px;
            position: relative;
        }

        .smallImg {
            height: 100%;
            width: 100%;
        }

        .bigBox {
            height: 600px;
            width: 600px;
            background: #ccc;
            position: absolute;
            right: -600px;
            top: 0;
            overflow: hidden;
            display: none;
        }

        /* 大图的尺寸
        遮罩 / bigBox  =  小图  / 大图
        200 / 600    =  430 / 1290
     */
        .bigBox img {
            height: 1290px;
            width: 1290px;
            position: absolute;
            display: block;
        }

        .filter {
            height: 200px;
            width: 200px;
            background: rgba(0, 0, 0, 0.6);
            position: absolute;
            top: 0;
            left: 0;
            cursor: move;
            display: none;
        }

        /* 下面轮播图 */
        .productList {
            height: 100px;
            width: 430px;
            background: pink;
        }

        .productList span {
            display: block;
            float: left;
            height: 100px;
            width: 15px;
            background: #000;
            font-size: 14px;
            color: #fff;
            text-align: center;
            line-height: 100px;
            font-weight: 900;
            cursor: pointer;
        }

        .imgListShow {
            height: 100px;
            width: 400px;
            background: pink;
            float: left;
            position: relative;
            overflow: hidden;
        }

        .listBox {
            height: 100px;
            position: absolute;

        }

        .listBox article {
            box-sizing: border-box;
            height: 100px;
            width: 100px;
            border: 3px solid #ccc;
            float: left;
            cursor: pointer;
        }

        .listBox article img {
            height: 100%;
            width: 100%;
        }
    </style>
</head>

<body>
    <section class="showBox">
        <div class="productImg">
            <img src="./img2/1.jpg" alt="" class="smallImg">
            <div class="bigBox">
                <img src="./img2/1.jpg" alt="">
            </div>
            <span class="filter"></span>
        </div>

        <div class="productList">
            <span id="pre"><</span> 
            <div class="imgListShow">
                    <div class="listBox">
                        <article><img src="./img2/1.jpg" alt=""></article>
                        <article><img src="./img2/2.jpg" alt=""></article>
                        <article><img src="./img2/3.jpg" alt=""></article>
                        <article><img src="./img2/4.jpg" alt=""></article>
                        <article><img src="./img2/5.jpg" alt=""></article>
                        <article><img src="./img2/6.jpg" alt=""></article>
                        <article><img src="./img2/7.jpg" alt=""></article>
                    </div>
            </div>
            <span id="next">></span>
        </div>
    </section>

    <script src="../../myAPi/myApi.js/myAPI.js"></script>
    <script src="../../myAPi/myApi.js/move.js"></script>

    <script>
    
        function Maginfy(){
               this.oShowBox = $('.showBox')[0],
               this.oProductImg = $('.productImg')[0],
               this.oSmallImg = $('.smallImg')[0],
               this.oBigBox = $('.bigBox')[0], 
               this.oFilter = $('.filter')[0],

               this.oProductList = $('.productImg')[0],
               this.oImgListShow = $('.imgListShow')[0],
               this.oListBox = $('.listBox')[0],
               this.aPre = $('#pre'),
               this.aNext = $('#next'),
               this.aArticle = $('article'),
               this.aImg = $('img');
               this.distance = this.aArticle[0].offsetWidth;
               this.count = 0;
               this.init();
        }
        Maginfy.prototype = {
            //初始化入口
            init : function() {
                //设置oListBox 的宽度
                this.oListBox.style.width = this.aArticle.length * this.distance  + 'px';
                this.eventBind();
                // this.switch();
            },
            mouseMove : function(e){
                e = e || window.event;
                preventDefault(e);
                let
                    l = e.pageX - this.oShowBox.offsetLeft - 
                    this.oFilter.offsetWidth / 2,
                    t = e.pageY - this.oShowBox.offsetTop - this.oFilter.offsetHeight / 2;
                    //对边界进行限定
                    l = l < 0 ? 0 : (l > 230 ? 230 : l);
                    t = t < 0 ? 0 : (t > 230 ? 230 : t);
                    //遮罩层跟着鼠标进行移动
                    this.oFilter.style.left = l + 'px';
                    this.oFilter.style.top = t +'px';
                    //大图的移动
                    this.oBigBox.firstElementChild.style.left = - l * 3 + 'px';
                    this.oBigBox.firstElementChild.style.top = -t * 3 + 'px';
            } ,
            toImg : function(){
                move(this.oListBox,{'left': -this.distance * this.count});
            },
            next : function(){
                if(this.count >= this.aArticle.length - 4){
                    this.count = this.aArticle.length - 4;
                }else{
                    this.count++;
                }
                this.toImg();
            },
            pre : function(){
                if(this.count <= 0){
                    this.count = 0; 
            }else{
                this.count--;
            }
                this.toImg();
            },
            switch : function(i){
                // for(let i = 0, k = this.aArticle.length; i < k ; i++){
                        this.oSmallImg.src = this.aArticle[i].firstElementChild.src;
                        this.oBigBox.firstElementChild.src = this.aArticle[i].firstElementChild.src;
                // }
               
            },
            block : function(){
                this.oFilter.style.display = 'block';
                this.oBigBox.style.display = 'block';
                addEventListener(this.oProductImg,'mousemove',this.mouseMove.bind(this));
               
            },
            none : function(){
                this.oFilter.style.display = 'none';
                this.oBigBox.style.display = 'none';
            },
            eventBind : function(){
                this.oProductImg.addEventListener('mouseover',this.block.bind(this));
                this.oProductImg.addEventListener('mouseout',this.none.bind(this));
                this.aPre.addEventListener('click',this.pre.bind(this));
                this.aNext.addEventListener('click',this.next.bind(this));
                for(let i = 0, k = this.aArticle.length; i < k ; i++){
                    this.aArticle[i].addEventListener('mouseover',this.switch.bind(this,i));
                }
               
            }
        }
        new Maginfy();
    </script>
</body>

</html>

8.面向对象实现打字游戏
<!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>
    *{
        margin:0;
        padding:0;
    }
    html,body{
        height:100%;
    }
    body{
        background:url(./img/timg.jpg);
        background-size:100% 100%;
        overflow: hidden;
    }
    div{
        height:80px;
        width:80px;
        background:url(./img/plan.png) no-repeat;
        background-size:100% 100%;
        font-size:40PX;
        font-weight:bold;
        text-align:center;
        line-height:80px;
        color:orange;
        position:absolute;
    }
    </style>
</head>
<script src="../../myAPi/myApi.js/myAPI.js"></script>
<body>
    <!-- <div class="plan">A</div> -->
    <script>
    /*
        逻辑:
            1.背景的移动
            2.创建飞机
            3.飞机的移动
            4.飞机的爆炸
            5.键盘事件触发
        
    
    */ 
   function Plan(){
       //获取视口的宽和高
       this.vw = document.documentElement.clientWidth - 80;
       this.vh = document.documentElement.clientHeight - 80;
       this.init();
   }
   Plan.prototype = {
        init: function(){
            this.bgMove();
            // this.createPlan();
            // this.PlanMove();
            this.eventBind();
        },
        //背景的移动
        bgMove : function(){
            //速度
            var speed = 5;
            setInterval( ()=>{
                speed += 5;
                //背景图的移动(backgroundPositionY = background-position-Y)
            document.body.style.backgroundPositionY = speed + 'px';
            }, 50)
        },
        //创建飞机
        createPlan : function(){
            //动态创建飞机
            var _this = this;
            setInterval( ()=>{
                let createDiv = document.createElement('div');
                //添加内容(先随机产生65-90,在将其转换为字母)
                createDiv.innerHTML = String.fromCharCode(randomNumber(65,90));
                //在哪创建
                createDiv.style.top = 0;
                createDiv.style.left = randomNumber(0,_this.vw) +'px';
                //注:添加元素直接添加
                document.body.appendChild(createDiv);
                //飞机创建后,进行移动
                _this.planMove(createDiv);
            },800)
        },
        //飞机的移动(这时并不知道谁在移动,需要设个行参)
        planMove : function(ele){
            let speed = 5;
            let _this = this;
            ele.timer = setInterval(function(){
                //元素移动
                ele.style.top = ele.offsetTop + speed +'px';
                //当飞机到低部,清除定时器,游戏结束
                if(ele.offsetTop >= _this.vh){
                    clearInterval(ele.timer);
                    alert('游戏结束');
                    //重新刷新页面
                    location.reload();
                }
            },100)

        } ,
        //飞机的爆炸(需要确定是那个一个飞机爆炸)(确定位置)
        blast : function(l,t){
            //创建爆炸的效果
            let img = document.createElement('img');
            img.src = './img/die.gif';
            //给图片添加样式
            img.style.cssText = 'width:80px;height:80px;position:absolute;left:'+ l +'px;top:'+ t +'px';
            //将创建的飞机添加到body 中
            document.body.appendChild(img);
            //爆炸完 清除图片
            setTimeout(() =>{
               img.remove();
            },400)

        },
        //键盘事件
        eventFn: function(e){
            e = e || window.event;
            //获取按键的 ascii
            let keyCode = e.keyCode || e.which;
            //如果键盘上的ascii  码 和飞机上的ascii 码一致 飞机销毁
            //对所有的飞机进行获取
            let allPlan = document.getElementsByTagName('div');
            //进行循环遍历
            //注:此时要用let 形成块级作用域
            for(let i = 0, k = allPlan.length; i < k; i++){
                //获取飞机中字母的ascii 值
                let num = allPlan[i].innerText.charCodeAt(0);
                console.log(allPlan[i]);
                //如果飞机的ascii 值和 键盘的ascii 值 相等
                if( keyCode == num){
                    //飞机击中,记录飞机的位置
                    let left = allPlan[i].offsetLeft;
                    let top = allPlan[i].offsetTop;
                    console.log(allPlan[i].innerHTML);
                    allPlan[i].remove();
                    //同时飞机爆炸
                    this.blast(left,top);
                }
            }

        },
        eventBind :function(){
            addEventListener(document,'keydown',this.eventFn.bind(this));
            //点击页面时,游戏开始
            addEventListener(document,'click',this.createPlan.bind(this));
        }

   }
   new Plan();
    </script>
</body>
</html>