js面向对象

来源:互联网 发布:普陀区数据恢复 编辑:程序博客网 时间:2024/06/05 03:12

js面向对象的由来:

一般情况下,我们会一个接一个的写函数function,遇到重复的还得copy,如果一不小心函数重名了,不知道从何开始查找错误,总是用面向过程的编程思想来写JS代码,为了防止这种低级错误的出现,以及使自己的代码更有条理,可以用js面向对象的思想解决。

1、

引入例子:在JS中每一个function就是一个对象,例如

function HelloWorld()
{
    alert('hello world!');
}

那么我们在使用的时候就可以把它当成一个对象来使用,比如使用如下的测试函数:

function _test()
{
    var obj = new HelloWorld();
}

那么在调用_test方法后就会弹出hello world!的提示框,也就是调用了HelloWorld()对象(函数)。

在这里HelloWorld这个对象没有任何属性和方法,它只有一个构造方法HelloWorld(),

当使用new进行对象创建的时候,就调用了它的构造方法。这也是我们最简单的对象了,当然了,一个对象肯定是要赋予它属性方法的。

其实我觉得

对象的组成:
    方法--函数
    属性--变量

2、解释对象的方法和属性

例如:var arr=[1,2,3,4,5];检测一下类型 alert(typeof arr)--》object;

其中alert(arr.length)  //数组的length属性;arr.push(6)        //数组的push()  方法

当然也可以:var a=10;  arr.a=8;给arr数组添加一个自定义a属性;

arr.fn=function(){ alert("b") } arr.fn()给arr数组添加一个自定义fn方法;

3、this的使用

oDiv.onclick=function(){
            aler(this)   //this  当前的方法属于谁,this就是谁(当然,这里的this是指oDiv)
 }
4、 新建对象new

var obj=new Object();//定义一个新对象

obj.aaa=12;  //添加属性

③obj.show=function(){  //添加方法
       alert(this.aaa)
   }

 obj.show()

5、封装

设想一下,每个添加的方法模型都是一样的,按照平时的想法就是一遍遍的copy

所以为了减少工作量,可以把这个模板封装起来,用到时调用就行了。


首先是封装之工厂模式:原材料--加工---出厂--使用

  //构造函数
        function creatPerson(name,sex){
            //1、创建一个对象(原材料
            var obj=new Object();
            //2、给对象添加属性和相应的方法(加工
            obj.name=name;
            obj.sex=sex;
            obj.showName=function(){
                alert("我的名字叫:"+this.name)
            }
            obj.showSex=function(){
                alert("我的性别是:"+this.sex)
            }
            //3、return出这个加工好的object (出厂)
            return obj  //返回对象,能够让外部用的到
        }

4、var p1=creatPerson("blue","男");       p1.showName();    p1.showSex();//调用构造函数,返回方法
    缺点每次调用,相当于new一个新对象,虽然是集成出的方法,但都是有自己的方法函数,还不算是真正的模型。

测试一下alert(  p1.showName()==  p2.showName());返回false,说明并不是同一个方法。


6、真正的模型

 //构造函数
        //用this来代替内容
        function creatPerson(name,sex){
          //假象系统内部的工作流程
          //  var
this=new object
            this.name=name;
            this.sex=sex;
            this.showName=function(){
                alert("我的名字叫:"+this.name)
            }
            this.showSex=function(){
                alert("我的性别是:"+this.sex)
            }
            //假象系统内部的工作流程
            //return
this
        }


        var p1=
new creatPerson("blue","男");   p1.showName();    p1.showSex();

测试一下alert(  p1.showName()==  p2.showName());返回true,说明同一个方法,同一个模型。也就是把相同的方法抽出来封装成一个公共的模型方便使用

7、原型的引入prototype

 var arr1=new Array(1,2,3,4,5);

 //用prototype原型来创建一个sum方法
        Array.prototype.sum=function(){    //prototype(原型)  类似于Demo,模型
            var result=0;
            var i=0;
            for(i=0;i<this.length;i++){
                result+=this[i]
            }
            return result
        }

alert(arr1.sum())

此时  var arr2=new Array(12,2,3,4,5);    alert(arr1.sum==arr2.sum)

8、原型之改变简化creatPerson上面的例子

//        function CreatePerson(name,sex){
//            this.name=name;
//            this.sex=sex
//        }
//        CreatePerson.prototype.showName = function(){
//            alert("我的名字叫:"+this.name)
//        }
//        CreatePerson.prototype.showSex = function(){
//            alert("我的名字叫:"+this.sex)
//        }
//        var p1=new CreatePerson("blue","男")
//        var p2=new CreatePerson("lucy","女")
//        p1.showName();
//        p1.showSex();
//        p2.showName();
//        p2.showSex();
//        alert(p1.showSex==p2.showSex)


        //构造函数命名的规则:首字母大写  例如:new Date()  new Array()


        //总结:
        //构造函数中添加的是属性,在原型中添加的是方法
        //每个对象的属性各不相同,但是可以调用的同样的方法

9、原型例子之添零

        //Array是一个系统的对象,但是tools并不是系统对象
        function Tools(){};
        Tools.prototype.addZero=function(_num){
            if(_num<10){
                _num="0"+_num;
            }else{
                _num=_num
            }
            return _num
        }
        var t=new Tools();
        console.log(t.addZero(3))

并不是非要有属性


10、原型优先级

     Array.prototype.a=12  //类似于css中的class
        var arr=[1,2,3,4,5] //定义的新数组
       // alert(arr.a)  //来自于原型的内容
        arr.a=10;    //类似于css中的行内样式
        alert(arr.a)


        delete arr.a; //用delete方法来删除arr中的a属性
        alert(arr.a)

二、面向对象高级

1、JSON方式的面向对象

      //但凡是能在js中出现的内容,全部都能放在json中
//        var obj={a:12,b:5,c:function(){
//            alert("abc")
//        }}
//        obj.c()
        var p1={
            name:'blue',
            sex:"男",
            showName:function(){
                alert("这是我的名字"+this.name)
            },
            showSex:function(){
                alert("这是我的性别"+this.sex)
            }
        }
        p1.showName();
        p1.showSex();
        //优点:减少了构造函数,原型等编写
        //缺点:如果有两个这样子的方法,就要写n多个,所以json更适合一个对象的操作


2、拖拽原版js

        //onmousedown鼠标按下事件    onmousemove鼠标移动事件  onmouseup鼠标离开事件
        window.onload=function(){
            var oDiv=document.getElementById("div1")
            oDiv.onmousedown=function(ev){
                var oEvent=ev||event; //要捕捉的鼠标的位置
                var disX=oEvent.clientX-oDiv.offsetLeft;
                var disY=oEvent.clientY-oDiv.offsetTop;
                document.onmousemove=function(ev){
                    var oEvent=ev||event;
                    oDiv.style.left=oEvent.clientX-disX+"px";
                    oDiv.style.top=oEvent.clientY-disY+"px";
                }
                document.onmouseup=function(){
                    document.onmousemove=null;
                    document.onmousedown=null;
                }


            }


        }

注意:要给div进行定位position

3、面向对象的拖拽

   var oDiv=null;
        var disX=0;
        var disY=0;
        window.onload=function(){
            oDiv=document.getElementById("div1")
            oDiv.onmousedown=fnDown
        }
        //1.先把里面的函数领出来,并且重新命名(onmousedown    onmousemove   onmouseup)
        function fnDown(ev){
            var oEvent=ev||event; //要捕捉的鼠标的位置
            var disX=oEvent.clientX-oDiv.offsetLeft;
            var disY=oEvent.clientY-oDiv.offsetTop;
            document.onmousemove=fnMove;
            document.onmouseup=fnUp;
        }
        function fnMove(ev){
            var oEvent=ev||event;
            oDiv.style.left=oEvent.clientX-disX+"px";
            oDiv.style.top=oEvent.clientY-disY+"px";
        }
        function fnUp(){
            document.onmousemove=null;
            document.onmousedown=null;
        }
        //2.把oDiv领出来变成全局变量,通过谷歌纠错,把disX和disY也领出来变成全局变量

3进一步进化拖拽


        //最后一步就是window.onload下调用
        window.onload=function(){
            new Drag("div1")
        }
        //4.把全局的变量变成一个属性,该加this的加this
//        var oDiv=null;
//        var disX=0;
//        var disY=0;
        //3.把Window.onload修改一下,变成构造函数,传ID
        function Drag(id){
            var _this=this;
            this.disX=0;
            this.disY=0;
            this.oDiv=document.getElementById(id)
            this.oDiv.onmousedown=function(){
                _this.fnDown()
            }
        }
        //5.给Drag添加原型方法(上面的fnDown函数已经变成了方法,所以说还要加this,各种属性也要加this,
        // 需要注意的是函数的this的方法的添加)
        Drag.prototype.fnDown=function (ev){
            var _this=this;
            var oEvent=ev||event; //要捕捉的鼠标的位置
            this.disX=oEvent.clientX-this.oDiv.offsetLeft;
            this.disY=oEvent.clientY-this.oDiv.offsetTop;
            document.onmousemove=function(){
                _this.fnMove()
            };
            document.onmouseup=function(){
                _this.fnUp()
            };
        }
        Drag.prototype.fnMove=function (ev){
            var oEvent=ev||event;
            this.oDiv.style.left=oEvent.clientX-this.disX+"px";
            this.oDiv.style.top=oEvent.clientY-this.disY+"px";
        }
        Drag.prototype.fnUp=function(){
            document.onmousemove=null;
            document.onmousedown=null;
        }

4、继承1

  function Person(name,sex){
            this.name=name;
            this.sex=sex;
        }
        Person.prototype.showName=function(){
            alert(this.name)
        }
        Person.prototype.showSex=function(){
            alert(this.sex)
        }



        function Worker(name,sex,job){
//            alert(this)
            Person.call(this,name,sex)//用call方法来继承父级的内容
            this.job=job   //再添加子类的属性叫job
        }
        //继承方法的方式
        Worker.prototype=Person.prototype;
        //引用的话,子类会把父类也影响
        Worker.prototype.showJob=function(){
            alert(this.job)
        }
        alert(Person.prototype.showJob)
        var a1=new Worker("lucy","女","文员")
        a1.showName();
        a1.showSex();
        a1.showJob()

5、继承2

    //继承的是属性跟方法
        function Person(name,sex){
            this.name=name;
            this.sex=sex;
        }
        Person.prototype.showName=function(){
            alert(this.name)
        }
        Person.prototype.showSex=function(){
            alert(this.sex)
        }




        //-----------


        function Worker(name,sex,job){
//            alert(this)
            Person.call(this,name,sex)//用call方法来继承父级的内容
            this.job=job   //再添加子类的属性叫job
        }
       for(var i in Person.prototype){
           Worker.prototype[i]=Person.prototype[i]
       }
       Worker.prototype.showJob=function(){
            alert(this.job)
        }
        alert(Person.prototype.showJob)  //用循环来改变结果(为了不让子类来影响父级)
        var a1=new Worker("lucy","女","文员")
        a1.showName();
        a1.showSex();
        a1.showJob()










原创粉丝点击