Skip to content

一、上升到面向对象

  • 面向对象的本质:定义不同的类,让类的实例工作。
  • 面向对象的优点:程序编写更清晰,代码结构更严密,使代码更健壮更利于维护。
  • 面向对象经常用到的场合:需要封装和复用性场合(组件思维)。

1. 红绿灯

  • 页面上做一个红绿灯,点击红灯就变黄,点击黄灯就变绿,点击绿灯就变回红灯。
  • 如果页面上有100个这样的红绿灯呢?
  • 使用面向对象编程,就能以"组件化"的思维解决大量红绿灯互相冲突的问题。
  • 面向对象编程,最重要的就是编写类
  • TrafficLight类
    • 请思考,红绿灯TrafficLight类有哪些属性和方法呢?
    • 属性:自己的当前颜色color、自己的DOM元素dom
    • 方法:初始化init()、切换颜色changeColor()、绑定事件 bindEvent()
  • 代码实现
    html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
            #box img{
                width: 80px;
            }
        </style>
    </head>
    <body>
        <div id="box"></div>
    
        <script>
            // 定义红绿灯类
            function TrafficLight() {
                // 颜色属性,一开始都是红色
                // 红色1、黄色2、绿色3
                this.color = 1;
                // 调用自己的初始化方法
                this.init();
                // 绑定监听
                this.bindEvent();
            }
            // 初始化方法
            TrafficLight.prototype.init = function() {
                // 创建自己的DOM
                this.dom = document.createElement('img');
                // 设置src属性
                this.dom.src = 'images/' + this.color + '.jpg';
                box.appendChild(this.dom);
            };
            // 绑定监听
            TrafficLight.prototype.bindEvent = function() {
                // 备份上下文,这里的this指的是JS的实例
                var self = this;
                // 当自己的dom被点击的时候
                this.dom.onclick = function () {
                    // 当被点击的时候,调用自己的changeColor方法
                    self.changeColor();
                };
            }
            // 改变颜色
            TrafficLight.prototype.changeColor = function () {
                // 改变自己的color属性,从而有一种“自治”的感觉,自己管理自己,不干扰别的红绿灯
                this.color ++;
                if (this.color == 4) {
                    this.color = 1;
                }
                // 光color属性变化没有用,还要更改自己的dom的src属性
                this.dom.src = 'images/' + this.color + '.jpg';
            };
    
            // 得到盒子
            var box = document.getElementById('box');
    
    
            // 实例化100个
            var count = 100;
    
            while(count--){
                new TrafficLight();
            }
             
        </script>
    
    </body>
    </html>

2. 炫彩小球

  • 把每个小球实例都放到同一个数组中
  • 只需要使用1个定时器,在每一帧遍历每个小球,调用它们的update方法
  • 代码实现
    html
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
            body {
                background-color: black;
                overflow: hidden;
            }
    
            .ball {
                position: absolute;
                border-radius: 50%;
            }
        </style>
    </head>
    
    <body>
        <script>
            // 小球类
            function Ball(x, y) {
                // 属性x、y表示的是圆心的坐标
                this.x = x;
                this.y = y;
                // 半径属性
                this.r = 20;
                // 透明度
                this.opacity = 1;
                // 小球背景颜色,从颜色数组中随机选择一个颜色
                this.color = colorArr[parseInt(Math.random() * colorArr.length)];
                // 这个小球的x增量和y的增量,使用do while语句,可以防止dX和dY都是零
                do {
                    this.dX = parseInt(Math.random() * 20) - 10;
                    this.dY = parseInt(Math.random() * 20) - 10;
                } while (this.dX == 0 && this.dY == 0)
    
                // 初始化
                this.init();
                // 把自己推入数组,注意,这里的this不是类本身,而是实例
                ballArr.push(this);
            }
            // 初始化方法
            Ball.prototype.init = function () {
                // 创建自己的dom
                this.dom = document.createElement('div');
                this.dom.className = 'ball';
                this.dom.style.width = this.r * 2 + 'px';
                this.dom.style.height = this.r * 2 + 'px';
                this.dom.style.left = this.x - this.r + 'px';
                this.dom.style.top = this.y - this.r + 'px';
                this.dom.style.backgroundColor = this.color;
                // 上树
                document.body.appendChild(this.dom);
            };
            // 更新
            Ball.prototype.update = function () {
                // 位置改变
                this.x += this.dX;
                this.y -= this.dY;
                // 半径改变
                this.r += 0.2;
                // 透明度改变
                this.opacity -= 0.01;
                this.dom.style.width = this.r * 2 + 'px';
                this.dom.style.height = this.r * 2 + 'px';
                this.dom.style.left = this.x - this.r + 'px';
                this.dom.style.top = this.y - this.r + 'px';
                this.dom.style.opacity = this.opacity;
    
                // 当透明度小于0的时候,就需要从数组中删除自己,DOM元素也要删掉自己
                if (this.opacity < 0) {
                    // 从数组中删除自己
                    for (var i = 0; i < ballArr.length; i++) {
                        if (ballArr[i] == this) {
                            ballArr.splice(i, 1);
                        }
                    }
                    // 还要删除自己的dom
                    document.body.removeChild(this.dom);
                }
            };
    
    
            // 把所有的小球实例都放到一个数组中
            var ballArr = [];
    
            // 初始颜色数组
            var colorArr = ['#66CCCC', '#CCFF66', '#FF99CC', '#FF6666',
        '#CC3399', '#FF6600'];
    
            // 定时器,负责更新所有的小球实例
            setInterval(function () {
                // 遍历数组,调用调用的update方法
                for (var i = 0; i < ballArr.length; i++) {
                    ballArr[i].update();
                }
            }, 20);
    
            // 鼠标指针的监听
            document.onmousemove = function (e) {
                // 得到鼠标指针的位置
                var x = e.clientX;
                var y = e.clientY;
    
                new Ball(x, y);
            };
        </script>
    </body>
    
    </html>

Released under the MIT License.