js继承

作者: 感觉不错哦 | 来源:发表于2018-11-13 14:53 被阅读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写法

    相关文章

      网友评论

          本文标题:js继承

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