JavaScript面向对象(1)-封装

1、什么是面向对象编程?
用对象的思想去写代码,就是面向对象编程(OOP)。

2、面向对象编程(OOP)的特点
封装、继承、多态。

3、对象的组成
方法(行为、操作)——函数:过程、动态的(对象下面的函数)
属性——变量:状态、静态的(对象下面的变量)

4、创建对象的模式
通常情况下,我们在创建一个对象时会采用下列方式:

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

上面创建代码的方式叫做对象字面量。对象字面量虽然可以创建对象,但是在创建多个对象时会产生代码的大量重复问题:

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

var obj2 = new Object();  //创建了第二个空的对象
obj2 .name = '小强';  //属性
obj2 .showName = function(){  //方法
    alert(this.name);
};
obj2 .showName();

为了解决上面的问题,可以封装一个函数,利用传参的方式创建多个对象:

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

上面的封装函数即创建对象的另一种模式:工厂模式,工厂模式解决了代码重复的问题,但是还存在另一个问题,那就是p1和p2之间没有内在的联系,不能反映出它们是同一个原型对象的实例。将工厂模式创建出来的对象和系统对象(如:var arr = new Array() )作对比,可以发现两者有两点不同:一是函数名称首字母大写,二是new一个在函数内部,一个在函数外部,将上面的封装函数首字母大写,并将new提出来,则得到以下模式:

function CreatePerson(name){
    this.name = name;
    this.showName = function(){
        alert( this.name );
    };
}
var p1 = new CreatePerson('小明');  //new后面的函数叫做构造函数。当new去调用一个函数,这个时候函数中的this就是创建出来的对象,且函数的返回值默认就是this(隐式返回),所以在函数内部不用再写return返回。
var p2 = new CreatePerson('小强');

而上面创建对象的模式即是构造函数模式。构造函数方法很好用,但是存在一个浪费内存的问题。对于每一个实例对象,CreatePerson方法都是一模一样的内容,每一次生成一个实例,就会多占用一些内存。这样既不环保,也缺乏效率。那么能不能让公有的属性和方法在内存中只生成一次,然后所有实例都指向那个内存地址呢?

alert( p1.showName == p2.showName );  //false

每一个构造函数都有一个prototype属性,指向另一个对象。这个对象的所有属性和方法,都会被构造函数的实例继承。我们可以把那些不变的属性和方法,直接定义在prototype对象上。这种方式即原型模式

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

5、面向对象编程实例:拖拽
先写出普通的写法,然后改成面向对象写法
》普通方法变型
-尽量不要出现函数嵌套函数
-可以有全局变量
-把onload中不是赋值的语句放到单独函数中
》改成面向对象
-Onload中创建对象
-全局变量就是属性
-函数就是方法
-改this指向问题

过程式写法:

<script type="text/javascript">
    window.onload=function(){
        var oDiv=document.getElementById("div1");
        var disX=0;
        var disY=0;

        oDiv.onmousedown=function(ev){
            var ev= ev || window.event;
            disX=ev.clientX-oDiv.offsetLeft;
            disY=ev.clientY-oDiv.offsetTop;

            document.onmousemove=function(ev){
                var ev=ev||window.event;
                oDiv.style.left=ev.clientX-disX+'px';
                oDiv.style.top=ev.clientY-disY+'px';
            }

            document.onmouseup=function(){
                document.onmousemove=null;
                document.onmouseup=null;
            }

            return false;
        }
    }
</script>

变形后为:

<script type="text/javascript">
    var oDiv=null;
    var disX=0;
    var disY=0;

    window.onload=function(){
        oDiv=document.getElementById("div1");
        oDiv.onmousedown=fnDown;
    }

    function fnDown(ev){
        var ev= ev || window.event;
        disX=ev.clientX-oDiv.offsetLeft;
        disY=ev.clientY-oDiv.offsetTop;

        document.onmousemove=fnMove;
        document.onmouseup=fnUp;

        return false;
    }

    function fnMove(ev){
        var ev=ev||window.event;
        oDiv.style.left=ev.clientX-disX+'px';
        oDiv.style.top=ev.clientY-disY+'px';
    }

    function fnUp(){
        document.onmousemove=null;
        document.onmouseup=null;
    }

</script>

改成面向对象写法:

<script type="text/javascript"> 
    window.onload=function(){
        var d1=new Drag('div1');  //onload函数中创建对象
        d1.init();
    }

    function Drag(id){  //构造函数
        this.oDiv=document.getElementById(id);
        this.disX=0;
        this.disY=0;
    }

    //构造函数的原型下面写方法
    Drag.prototype.init=function(){
        var This=this;
        this.oDiv.onmousedown=function(ev){
            var ev=ev || window.event;
            This.fnDown(ev);
            return false;
        };
    }

    Drag.prototype.fnDown=function(ev){
        var This=this;
        this.disX=ev.clientX-this.oDiv.offsetLeft;
        this.disY=ev.clientY-this.oDiv.offsetTop;

        document.onmousemove=function(ev){
            var ev=ev || window.event;
            This.fnMove(ev);
        };
        document.onmouseup=this.fnUp;

    }

    Drag.prototype.fnMove=function(ev){

        this.oDiv.style.left=ev.clientX-this.disX+'px';
        this.oDiv.style.top=ev.clientY-this.disY+'px';
    }

    Drag.prototype.fnUp=function(){
        document.onmouseup=document.onmousemove=null;
    }

</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值