JavaScript中继承的几种方式

/在学习继承之前先了解一下call和apply/

1.call与apply
*/ 
   call与apply : 改变this的指向
   事件处理函数中 this----->触发事件的对象
   普通函数中    this------>window
   构造函数中   this ----> 实例对象
   实例对象的方法中 this---对象
 */
 
 
 //1. call
     //sum.call(指向this的指向)
     function sum(){
         console.log(this);//window
     }
     sum();
     sum.call(sum);//sum函数
     sum.call(1); //Number {1}
     sum.call("1"); //String {"1"}
     sum.call([]); //[]


     //有参数  sun.call(this的指向,参数1,参数2,....)
     function sun(a,b){
         console.log(this);//window
         console.log(a+b);
     }
     sun(10,20);//30
     sun.call(document,40,50); //document   90


     var obj1 = {
         "name":"如花",
         "toString":function(){
             console.log(this.name);
         }
     }


     var obj2 = {
         "name":"似玉",
         "toString":function(){
             console.log(this.name);
         }
     }

     obj2.toString.call(obj1); //如花


     //sum.apply(this的指向,[参数1,参数2]);
     function sun(a,b){
         console.log(this);
         console.log(a+b);
     }
     sun.apply(document,[10,20]);

    //可以用apply找出数组最大值
     var arr = [5,7,9,2,6,0,4,1];
     console.log(Math.max.apply(1,arr)); 
 
 
 */call和apply的作用和用法是一样的,只是apply在传参的时候形式不一样,参数要用中括号扩上*/
2.面向对象的几种继承方式

(1)原型链继承

        //1.声明父类构造函数
        function Student(name,id){
            this.name = name;
            this.id = id;
            this.arr = [1,2,3];
        }
        Student.prototype.study = function(){
            console.log("好好睡觉,好好长身体,好好休息");
        }

        //2.声明一个子类构造函数
        function SmallStudent(){
            this.homeWork = function(){
                console.log("作业太少");
            }
        }

        //3.继承操作 原型链继承 子类的原型对象指向父类的实例对象
        SmallStudent.prototype = new Student("小明",007);

        var ss1 = new SmallStudent();
        console.log(ss1); SmallStudent {homeWork: ƒ}
        ss1.study(); //好好睡觉,好好长身体,好好休息
        console.log(ss1.name); //小明

        console.log(ss1.arr); //[1,2,3]
        ss1.arr.push(4); 
        console.log(ss1.arr); //[1,2,3,4]


        var ss2 = new SmallStudent();
        console.log(ss2.name); //小明

        console.log(ss2.arr); //[1,2,3,4]


*/原型链,先找实例对象本身,有就用自己的,没有就找实例对象中的__proto__(prototype),依次往父级找,一直找不到返回undefined*/

*/缺点:不能传参,如果继承下来引用类型数据,一改全改*/

在这里插入图片描述
在这里插入图片描述

(2)对象冒充继承

       //1.声明父类构造函数
        function Student(name,id){ //window---->SmallStudent
            this.name = name;
            this.id = id;
            this.arr = [1,2,3];
        }
        Student.prototype.study = function(){
            console.log("好好睡觉,好好长身体,好好休息");
        }

        //2.声明一个子类构造函数
        function SmallStudent(name,id){
            /* 
              this.name = name;
              this.id = id;
              this.arr = [1,2,3];
             */
             //创建一个空对象  this--空对象
             //this--->
            Student.call(this,name,id);//改变Student里面的this指向
            this.homeWork = function(){
                console.log("作业太少");
            }
        }
        var ss1 = new SmallStudent("小红",007);
        console.log(ss1);//SmallStudent {name: "小红", id: 7, arr: Array(3), homeWork: ƒ}
        ss1.arr.push(4);
        console.log(ss1.arr);// [1, 2, 3, 4]

        var ss2 = new SmallStudent("小明",007);
        console.log(ss2);//SmallStudent {name: "小明", id: 7, arr: Array(3), homeWork: ƒ}
        console.log(ss2.arr);//[1, 2, 3]


        ss1.study(); //Uncaught TypeError: ss1.study is not a function不能继承原型对象中的内容


*/缺点:解决了不能传参的问题,但是新的问题是继承不了原型中的内容*/

(3)组合继承: 对象冒充(构造函数)+原型继承(原型对象)

//1.声明父类构造函数
        function Student(name,id){ //window---->SmallStudent
            this.name = name;
            this.id = id;
            this.arr = [1,2,3];
        }
        Student.prototype.study = function(){
            console.log("好好睡觉,好好长身体,好好休息");
        }

        //2.声明一个子类构造函数
        function SmallStudent(name,id){
            //对象冒充继承:继承构造函数中个的内容
            Student.call(this,name,id);
            this.homeWork = function(){
                console.log("作业太少");
            }
        }

        //原型链继承;继承原型对象中的内容
        SmallStudent.prototype = new Student();
        var ss1 = new SmallStudent("小美","007");
        console.log(ss1);


        ss1.study();//好好睡觉,好好长身体,好好休息

4.面向对象继承的实例

拖拽+控制范围

<div id="box1"></div>
    <div id="box2"></div>
    <script>
        //创建构造函数
        //属性,方法
             //创建父函数,具有拖拽效果
            function Drag(id) {
                this.oDiv = document.getElementById(id);
                this.x = 0;
                this.y = 0;
                var _this = this;
                this.oDiv.onmousedown = function (ev) {
                    _this.mouseDown(

                    );

                    document.onmousemove = function (ev) {
                        _this.mouseMove();
                    }
                    document.onmouseup = function () {
                        _this.mouseUp();
                    }
                    return false;
                }
               
            }
            Drag.prototype = {
                "mouseDown": function () {
                    var ev = window.event || ev;
                    this.x = ev.clientX - this.oDiv.offsetLeft;
                    this.y = ev.clientY - this.oDiv.offsetTop;
                },
                "mouseMove": function () {
                    var ev = window.event || ev;
                    var l = ev.clientX;
                    var t = ev.clientY;
                    this.oDiv.style.top = t - this.y + "px";
                    this.oDiv.style.left = l - this.x + "px";

                },
                "mouseUp": function () {
                    document.onmousemove = document.onmouseup = null;
                }
            }
            //进行继承连接,父元素的实例对象赋值给子元素的原型
            Limit.prototype= new Drag("box1");//原型链继承
            //创建子函数,对象冒充继承Drag的属性和方法---
                function Limit(id){
                Drag.call(this,id);              
            }
            //添加Limit比Drag多的方法,限制拖拽范围
            Limit.prototype.mouseMove=function(ev){
                var ev = window.event||ev;
                var l=ev.clientX-this.y;
                var t=ev.clientY-this.x;
                if(l<0){l=0;}
                if(t<0){t=0;}
                if(l>document.documentElement.clientWidth-this.oDiv.offsetWidth){
                    l=document.documentElement.clientWidth-this.oDiv.offsetWidth+"px";
                }
                if(t>document.documentElement.clientHeight-this.oDiv.offsetHeight){
                    t=document.documentElement.clientHeight-this.oDiv.offsetHeight+"px";
                }
                this.oDiv.style.top=t+"px";
                this.oDiv.style.left=l+"px";

            }
            new Drag("box1");//box1可以拖拽
            new Limit("box2");//box2在拖拽的基础上还可以限制拖拽的范围

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值