js继承

2018-11-13  本文已影响96人  感觉不错哦

继承的概念我就不解释了,理解千千万,找一个属于自己的理解最不会忘

继承的主要作用就是获取属性跟方法

构造函数继承

我们新建html,编写一下js

        function Person(name,age,sex){//父构造函数
            this.name=name;
            this.age=age;
            this.sex=sex;
            this.showinfo=function(){
                alert('你的姓名是:'+this.name+',你今年'+this.age+'岁,你的性别是:'+this.sex);
            }
        }
        var p1=new Person('张三',100,'男');
        p1.showinfo()  输出的结果很明显

我们再写一个方法

        function Worker(name,age,sex,work){//子构造函数
            Person.apply(this,arguments);//在子对象构造函数中利用call或apply将父对象指向子对象的实例对象。
            this.work=work;
            this.showinfo=function(){
                alert('你的姓名是:'+this.name+',你今年'+this.age+'岁,你的性别是:'+this.sex+',你的工作是'+this.work);
            }
        }
        var w1=new Worker('wangwu',1000,'女','student');
        alert(w1.name);//属性继承来的  ‘wangwu’
        w1.showinfo();//方法也是继承来的,如果出现重名,子构造函数覆盖父构造函数的方法。。

最重要的一步就是第二行,Person.apply,改变了this这个是核心,因为参数比较多所以用apply存在数组中

混合继承

我们写一个方法,让效果更加明显,写一个元素拖拽的继承

    #box{
        width:100px;height:100px;background: red; position: absolute;
    }
    #box1{
        width:100px;height:100px;background: blue; position: absolute;left: 500px; top:100px;
    }


    <div id="box"></div>
    <div id="box1"></div>   html+css 小伙伴测试可以直接复制

在js中先构造一个函数

        function Drag(id){//创建一个构造函数
            this.shortx=null;
            this.shorty=null;
            this.div=document.getElementById(id); 编写一个方法用来获取元素
        }

        Drag.prototype.init=function(){                 我们在函数下的原型中声明一个init方法
            var that=this;                               把环境赋值给that,方便调用当前环境下的方法
            this.div.onmousedown=function(ev){
                var ev=ev||window.event;             此处是兼容处理
                that.down(ev);                              调用下方的down方法
                document.onmousemove=function(ev){
                    var ev=ev||window.event;
                    that.move(ev);
                }
                document.onmouseup=that.up;
                return false;
            }
        Drag.prototype.down=function(ev){
            this.shortx=ev.offsetX;
            this.shorty=ev.offsetY;
        };
        Drag.prototype.move=function(ev){
            this.div.style.left=ev.clientX-this.shortx+'px';
            this.div.style.top=ev.clientY-this.shorty+'px';
        };
        Drag.prototype.up=function(){  
            document.onmousemove=null;
            document.onmouseup=null;
        };

这是面向对象编程的类似写法,不知道大家能不能看懂,简单来说就是给函数Drag原型下申明了若干个方法,这是一个很简单的元素拖动,此时我们编写好方法其实就可以使用了

        var d1=new Drag('box');
        d1.init();

在编辑好函数之后,申明一个构造实例对象,注意对象,属性,方法三者之间的关系,只有属性是调用方法的,对象调用属性,属性调用方法,此时id为box的div就可以拖拽了,我们看看如何继承

        //混合继承:属性的继承
        function Draglimit(id){
            Drag.call(this,id);//属性的继承
        }

这就是混合继承,通过原型加构造函数继承,先进行方法的原型声明,然后通过call的this指向

混合继承有两种方式,第一种通过赋值
        //混合继承:属性的继承
        function Draglimit(id){
            Drag.call(this,id);//属性的继承
        }

        //混合继承:方法的继承1:一一赋值
        for(var i in Drag.prototype){
            Draglimit.prototype[i]=Drag.prototype[i];//一一赋值
        }

通过for in 循环将右边的展开赋值给左边,此时我们可以通过Draglimit构造一个对象

         var d2=new Draglimit('box1');
         d2.init();  

这样另一个div也是可以拖拽的

混合继承的第二种方式就是 原型继承
        Draglimit.prototype=new Drag();//等式两边都指向同一个地方,父类和子类的构造函数全局指向父类
        Draglimit.prototype.constructor=Draglimit;

看不懂的小伙伴可以看看我的原型篇
https://www.jianshu.com/p/72156bc03ac1
此时我们可以再次构造一个对象

         var d2=new Draglimit('box1');
         d2.init();   

你会发现 也是可以拖拽的,说明我们继承成功,我们试着来编辑一下子类的私有属性

        Draglimit.prototype.move=function(ev){
            var l=ev.clientX-this.shortx;
            var t=ev.clientY-this.shorty;
            if(l<0){
                l=0;
            }
            
            if(t<0){
                t=0;
            }
            this.div.style.left=l+'px';
            this.div.style.top=t+'px';
        }

我给子类原型下的move重新写了一个方法,这是用来判断浏览器窗口的,防止它移出隐藏,此时子类的方法会覆盖父类的方法

大家可以参考下完整的代码 配合开始的css与div 不过核心还是在前面提到的赋值与原型

        function Drag(id){//创建一个构造函数
            this.shortx=null;
            this.shorty=null;
            this.div=document.getElementById(id);
        }
        Drag.prototype.init=function(){
            var that=this;
            this.div.onmousedown=function(ev){
                var ev=ev||window.event;
                that.down(ev);
                document.onmousemove=function(ev){
                    var ev=ev||window.event;
                    that.move(ev);
                }
                document.onmouseup=that.up;
                return false;
            }
            
        }
        Drag.prototype.down=function(ev){
            this.shortx=ev.offsetX;
            this.shorty=ev.offsetY;
        };
        Drag.prototype.move=function(ev){
            this.div.style.left=ev.clientX-this.shortx+'px';
            this.div.style.top=ev.clientY-this.shorty+'px';
        };
        Drag.prototype.up=function(){
            document.onmousemove=null;
            document.onmouseup=null;
        };  
        var d1=new Drag('box');
        d1.init();
        //混合继承:属性的继承
        function Draglimit(id){
            Drag.call(this,id);//属性的继承
        }
        //混合继承:方法的继承1:一一赋值
        // for(var i in Drag.prototype){
        //  Draglimit.prototype[i]=Drag.prototype[i];//一一赋值
        // }
        
        //混合继承:方法的继承2:原型继承,父类的实例给子类的原型
        Draglimit.prototype=new Drag();//等式两边都指向同一个地方,父类和子类的构造函数全局指向父类
        Draglimit.prototype.constructor=Draglimit;
        //子类独有的。
        Draglimit.prototype.move=function(ev){
            var l=ev.clientX-this.shortx;
            var t=ev.clientY-this.shorty;
            if(l<0){
                l=0;
            }
            
            if(t<0){
                t=0;
            }
            this.div.style.left=l+'px';
            this.div.style.top=t+'px';
        }
        
        
        // var d1=new Drag('box');
        // d1.init();
        
         var d2=new Draglimit('box1');
         d2.init();    

这就是稍微有点复杂的混合继承,通过构造函数与原型的继承

最后我们来看看ES6 class 类的继承,其实继承的方法还有很多,但是这三个是比较常见也是比较全面的,希望小伙伴能好好掌握

在JavaScript中没有类的概念,只有对象。虽然现在ES6继承经常使用class关键字,这让JavaScript看起来似乎是拥有了”类”,可表面看到的不一定是本质,对程序来说,写法上面带来简便,但对内部实现来说,没有任何好处。我们称呼这种为语法糖

    <style type="text/css">
        #box{
            width:100px;height:100px;background: red; position: absolute;
        }
        #box1{
            width:100px;height:100px;background: blue; position: absolute;left: 500px; top:100px;
        }
    </style>
</head>
<body>
    <div id="box"></div>
    <div id="box1"></div>

css html 不变,我们使用es6的继承

          class Drag{//创建一个类
            constructor(id){//类的属性 constructor属性必填  其实这个属性每当我们构造对象的时候都是存在的
                this.shortx=null;
                this.shorty=null;
                this.div=document.getElementById(id);
            }
      可以看看原来的对比
    // function Drag(id){//创建一个构造函数
        //  this.shortx=null;
        //  this.shorty=null;
        //  this.div=document.getElementById(id);
        // }

创建好之后,我们来构造方法

        class Drag{//创建一个类
            constructor(id){//类的属性
                this.shortx=null;
                this.shorty=null;
                this.div=document.getElementById(id);
            }
            init(){//类的方法  注意方法写在class 中
                var that=this;
                this.div.onmousedown=function(ev){
                    var ev=ev||window.event;
                    that.down(ev);
                    document.onmousemove=function(ev){
                        var ev=ev||window.event;
                        that.move(ev);
                    }
                    document.onmouseup=that.up;
                }
            }
            down(ev){
                this.shortx=ev.offsetX;
                this.shorty=ev.offsetY;
            }
            move(ev){
                this.div.style.left=ev.clientX-this.shortx+'px';
                this.div.style.top=ev.clientY-this.shorty+'px';
            }
            up(){
                document.onmousemove=null;
                document.onmouseup=null;
            }
        }      

同样我们要实例化

        var d1=new Drag('box');//通过类实例化
        d1.init();

此时div已经可以拖拽了,我们看看如何继承

        class Draglimit extends Drag{
            constructor(id){
                super(id);//将父类下面的属性和方法全局继承了
            }

这就是继承的格式,同样用class 类声明 通过extends继承,这一步是最关键的,constructor跟super指代父类的参数

        class Draglimit extends Drag{
            constructor(id){
                super(id);//将父类下面的属性和方法全局继承了
            }
            move(ev){
                var l=ev.clientX-this.shortx;
                var t=ev.clientY-this.shorty;
                if(l<0){
                    l=0;
                }
                
                if(t<0){
                    t=0;
                }
                this.div.style.left=l+'px';
                this.div.style.top=t+'px';
            }
        }
        var d2=new Draglimit('box1');
        d2.init();

同样我们给子类写个专属的,即可覆盖掉父类继承的方法

    <!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 type="text/css">
            #box{
                width:100px;height:100px;background: red; position: absolute;
            }
            #box1{
                width:100px;height:100px;background: blue; position: absolute;left: 500px; top:100px;
            }
        </style>
    </head>
    <body>
            <div id="box"></div>
            <div id="box1"></div>
    </body>
    <script>
                class Drag{//创建一个类
                    constructor(id){//类的属性
                        this.shortx=null;
                        this.shorty=null;
                        this.div=document.getElementById(id);
                    }
                    init(){//类的方法
                        var that=this;
                        this.div.onmousedown=function(ev){
                            var ev=ev||window.event;
                            that.down(ev);
                            document.onmousemove=function(ev){
                                var ev=ev||window.event;
                                that.move(ev);
                            }
                            document.onmouseup=that.up;
                        }
                    }
                    down(ev){
                        this.shortx=ev.offsetX;
                        this.shorty=ev.offsetY;
                    }
                    move(ev){
                        this.div.style.left=ev.clientX-this.shortx+'px';
                        this.div.style.top=ev.clientY-this.shorty+'px';
                    }
                    up(){
                        document.onmousemove=null;
                        document.onmouseup=null;
                    }
                }      

                var d1=new Drag('box');//通过类实例化
                d1.init();

                class Draglimit extends Drag{
                    constructor(id){
                        super(id);//将父类下面的属性和方法全局继承了
                    }
                    move(ev){
                        var l=ev.clientX-this.shortx;
                        var t=ev.clientY-this.shorty;
                        if(l<0){
                            l=0;
                        }
                        
                        if(t<0){
                            t=0;
                        }
                        this.div.style.left=l+'px';
                        this.div.style.top=t+'px';
                    }
                }
                var d2=new Draglimit('box1');
                d2.init();
                
    </script>
    </html>

如果小伙伴无法运行,试着使用谷歌浏览器,部分浏览器不支持ES6写法

上一篇下一篇

猜你喜欢

热点阅读