面向对象的编程(1)

作者: 故笙丶 | 来源:发表于2017-04-07 20:40 被阅读35次

    一.什么是面向对象编程

    1.用对象的思想去写代码,就是面向对象编程

    我们以前常用的编程方式可以是比较过程式的写法,定义变量,然后给变量添加各种事件,如编写一个简单的选项卡,这样的写法有一个缺点,那就是复用性不高,假如页面上不止一个选项卡,那么同样的代码可能要出现很多次。

    2.其实我们一直在使用对象

    我们平时使用的Array,Date都是系统的内置对象

    3.面向对象编程的特点,也可以说是优势:

    1)抽象:抓住核心问题

    2)封装:只能通过对象来访问方法

    3)继承:从已有对象上继承出新的对象(代码复用)

    4)多态:多对象的不同形态(同样是代码复用的方式,但是使用的比较少)

    4.对象的组成

    对象由属性和方法组成

    对象下面的变量我们称之为属性,对象下面的函数我们称之为方法

    二、创建第一个面向对象程序

    var obj = new Object();  //创建了一个空的对象
    //给对象添加属性和方法
    obj.name = '小明';  //属性
    obj.showName = function(){  //方法
        alert(this.name);
    };
    
    obj.showName();
    

    其实这就是一个完整的面向对象程序了,看起来是不是很简单~

    假设我们现在需要创建另外一个对象,那么我们只需要把代码再复制一遍,但是这样又有问题了,因为代码看起来不够优化,之前学习js的时候,学习到的思想就是如果有重复的代码,那么我们尽量把它封装成一个函数;在面向对象中,同样可以,只不过不叫封装函数了,我们称之为“工厂方式”。

    function CreatePerson(name){
        
        //1.原料
        var obj = new Object();
        //2.加工
        obj.name = name;
        obj.showName = function(){
            alert( this.name );
        };
        //3.出厂
        return obj;
        
    }
    
    var p1 = new CreatePerson('小明');
    p1.showName();
    var p2 = new CreatePerson('小强');
    p2.showName();
    

    这样看起来是不是简洁很多。

    这里有两个新的概念,我们知道,其实我们在调用函数的时候,是可以直接调用的,像这样:

    var p1 = CreatePerson('小明');
    

    那么前面加上new,又有什么区别呢?

    当new去调用一个函数 : 这个时候函数中的this就是创建出来的对象,而且函数的的返回值直接就是this(隐式返回)

    另外new后面调用的函数 : 叫做构造函数

    用来创建对象的函数,我们称之为构造函数。构造函数的特点:

    1)首字母大写(参考系统对象写法)

    2)New 关键字提取

    3)This指向为新创建的对象

    代码这样写同样还是存在问题,因为每创建一个对象,都要去创建一个方法,尽管这个方法做的是同一件事情,这样会造成内存浪费。

    我们知道每一个对象都是有原型的,假设我们把方法加在原型上,那由原型构造的每一个对象就都拥有这个方法了。

    function CreatePerson(name){ 
        this.name = name; 
    }
    CreatePerson.prototype.showName = function(){
        alert( this.name );
    };
    
    var p1 = new CreatePerson('小明');
    p1.showName();
    var p2 = new CreatePerson('小强');
    p2.showName();
    

    这样的话相同的方法在内存中就只存在一份了。

    我们来总结一下面向对象的写法:

    构造函数加属性,原型加方法

    function 构造函数(){
        this.属性
    }
    
    构造函数.原型.方法 = function(){};
    
    var 对象1 = new 构造函数();
    对象1.方法();
    

    三、面向对象编程实践(1)-选项卡改写

    1.原则:先写出普通的写法,然后改成面向对象写法

    1)普通方法变型
    • 尽量不要出现函数嵌套函数

    • 可以有全局变量

    • 把onload中不是赋值的语句放到单独函数中

    2)改成面向对象
    • 全局变量就是属性

    • 函数就是方法

    • Onload中创建对象

    • 改this指向问题(事件和定时器中this指向容易被修改)

    普通写法:

    html和css代码就不贴了

    window.onload = function(){
        var oWrap = document.getElementById('wrap');
        var aBtn = document.getElementsByTagName('input');
        var aDiv = oWrap.getElementsByTagName('div');
        for (var i = 0; i < aBtn.length; i++) {
            aBtn[i].index = i;
            aBtn[i].onclick = function () {
                for (var i = 0; i < aDiv.length; i++) {
                    aBtn[i].className = "";
                    aDiv[i].style.display = "none";
                }
                aDiv[this.index].style.display = "block";
                aBtn[this.index].className = "active";
            };
        }
    }
    

    根据改写原则变形

    var oWrap = null;
    var aBtn = null;
    var aDiv = null;
    
    window.onload = function(){
        
        oWrap = document.getElementById('wrap');
        aBtn = oWrap.getElementsByTagName('input');
        aDiv = oWrap.getElementsByTagName('div');
    
        init();
        
    };
    //初始化函数
    function init(){
    
        for(var i=0;i<aBtn.length;i++){
            aBtn[i].index = i;
            aBtn[i].onclick = change;
        }
    
    }
    
    function change(){
    
        for(var i=0;i<aBtn.length;i++){
            aBtn[i].className = '';
            aDiv[i].style.display = 'none';
        }
    
        this.className = 'active';
        aDiv[this.index].style.display = 'block';
    
    }
    

    呃。。改写之后好像更复杂了

    继续改

    function Tab(id) {
        this.oWrap = document.getElementById(id);
        this.aBtn = this.oWrap.getElementsByTagName('input');
        this.aDiv = this.oWrap.getElementsByTagName('div');
        this.iNow = 0;
    }
    
    Tab.prototype.init = function() {
        var that = this;
    
        for (var i = 0; i < that.aBtn.length; i++) {
            that.aBtn[i].index = i;
            that.aBtn[i].onclick = function () {
                that.change(this);
            };
        }
    
    };
    
    Tab.prototype.change = function(obj) {
    
        for (var i = 0; i < this.aDiv.length; i++) {
            this.aBtn[i].className = "";
            this.aDiv[i].style.display = "none";
        }
    
        this.aDiv[obj.index].style.display = "block";
        obj.className = "active";
    
    };
    var t1 = new Tab("wrap"); //传参是为了方便复用
    t1.init();//没用window.onload,那就写在后面,否则无法调用
    

    这里this、that傻傻分不清的,请看这里:函数进阶

    这样看起来虽然还是没有普通写法简单,但是如果要复用的话就方便多了,另外面向对象编程比较适用于复杂的项目。

    假如页面上还有另外一个选项卡,而且这个选项卡要求是自动播放的,那么我们只需要在原来的基础上加上:

    Tab.prototype.autoPaly = function () {
    
        var that = this;
    
        setInterval(function() {
            if(that.iNow == that.aBtn.length-1){
                that.iNow = 0;
            }
            else{
                that.iNow++;
            }
            for (var i = 0; i < that.aDiv.length; i++) {
                that.aBtn[i].className = "";
                that.aDiv[i].style.display = "none";
            }
            that.aDiv[that.iNow].style.display = "block";
            that.aBtn[that.iNow].className = "active";
    
        }, 2000);
    
    };
    var t2 = new Tab("wrap2");
    t2.init();
    t2.autoPaly();
    

    四、面向对象编程实践(2)-拖拽改写

    这里要特别注意一下event对象的位置。

    window.onload = function () {
        var d1 = new Drag('div1');
        d1.init();
    };
    //构造函数Drag
    function Drag(id) {
        this.oDiv = document.getElementById(id);
        this.disX = 0;
        this.disY = 0;
    }
    //初始化方法
    Drag.prototype.init = function () {
    
        var that = this;
    
        this.oDiv.onmousedown = function (e) {
            e = e||window.event; //event只能出现在事件函数当中,所以不能写在fnDown方法里面
            that.fnDown(e);
            return false;
        };
    
    
    };
    Drag.prototype.fnDown = function(e) {
        var that = this;
    
        this.disX = e.clientX - this.oDiv.offsetLeft;
        this.disY = e.clientY - this.oDiv.offsetTop;
    
        document.onmousemove = function(e){
            e = e||window.event;
            that.fnMove(e);
        };
    
        document.onmouseup = this.fnUp;//注意这里别加括号。。踩过的坑
    };
    
    Drag.prototype.fnMove = function(e) {
        this.oDiv.style.left = e.clientX - this.disX +'px';
        this.oDiv.style.top = e.clientY - this.disY + 'px';
    };
    
    Drag.prototype.fnUp = function() {
        document.onmousemove = null;
        document.onmouseup = null;
    };
    

    相关文章

      网友评论

      本文标题:面向对象的编程(1)

      本文链接:https://www.haomeiwen.com/subject/doqkattx.html