js继承语法详解

什么是继承?

        继承是发生在父子级关系中的现象
        继承 是 构造函数 的高级应用

        就是两个互为父子级关系的构造函数的应用
        子级构造函数,继承的是父级构造函数的属性和方法

        常见的继承操作,分为 ES5 的继承语法 和 ES6 的继承语法

ES6 的继承语法

    // 如何定义一个构造函数
    // ES5语法
    // function Fun1(name,age){
    //     // 定义属性
    //     this.name = name;
    //     this.age = age;
    // }
    // // 定义方法
    // Fun1.prototype.f1 = function(){
    //     console.log(this.name,this.age);
    // }

    // ES6语法
    // class Fun2{
    //     // 构造器中定义属性
    //     constructor(name,age){
    //         this.name = name;
    //         this.age = age;
    //     }

    //     // 定义方法
    //     f2(){
    //         console.log(this.name,this.age);
    //     }
    // }

    // ES6的继承语法
    // 先定义父级构造函数 Father
    // 通过 extends 来指定 继承的父级的构造函数名称
    // 在构造器 constructor 中 通过 super 来 指定,哪个属性来自于父级构造函数
    // extends 关键词 指定父级构造函数
    // super 指定 属性来源父级

    // 继承属性,如果父级中有多个属性
    // 在 super 中, 只继承一部分,并且只设定一部分,没有设定的,执行结果是 undefined

    // 父级的属性 可以 只继承部分
    // 其他的属性 如果没有操作, 是 undefined
    // 也可以在子级中,定义父级属性的数据数值

    // 子级中也可以定义新的属性和属性值




    // 定义父级构造函数

    function Father(name, age) {
        this.name = name;
        this.age = age;

    }
    Father.prototype.f1 = function() {
        console.log(this.name, this.age);
    }

    // extends 指定从 Father 构造函数中,执行继承操作
    class Son extends Father {
        constructor(name, age, sex) {
            // 在构造其中,通过 super 来指定,从父级继承来的属性

            // 继承父级的name
            super(name);
            // 自行定义父级的age
            this.age = age;
            // 自定义属性sex和sex的数值
            this.sex = sex;
        }

        // 自定义方法
        f2() {
            console.log('我是自定义的子级方法');
        }

    }

    const obj1 = new Father('张三', 18);
    // console.log(obj1);

    // 属性是直接继承父级中,定义的属性的形式
    // 方法是调用父级中定义的方法
    const obj2 = new Son('李四', 20, '男');
    console.log(obj2);
    /*
    总结  ES6的继承语法
    1,继承语法是为了,简化代码,防止重复代码的出现
    2,继承是两个构造函数之间的应用
    3,ES6语法,默认是继承父级构造函数的所有的属性和所有方法
        属性如果没有指定数据,执行结果是undefined
        方法是通过原型链,找到父级构造函数中,定义的方法
    4,语法形式:
      class 子级 extends 父级{
          constructor(属性参数...){

              先写继承的属性,再写自定义的属性
              super(继承父级的属性);

              自定义属性
          }

          自定义的方法
          自定义方法(){

          }
      }

    */
       /*

ES5 的继承语法

        作用也是为了优化代码,防止重复的代码内容的产生

        语法1:原型继承
        语法2:借用构造函数继承
        语法3:组合继承
    */

    /*
        原型继承
            所谓的原型继承,是通原型链来继承父级构造函数的内容
            两个构造函数,没办法直接相互关联,必须要通过构造函生成的实例化对象
            在 子级构造函数的 prototype 中,添加父级构造函数,生成的实例化对象
            子级构造函数的 属性 就是 实例化对象 中定义的属性
            子级构造函数的 方法 就是 父级构造函数 中定义的方法
    */

    // function Father(name,age){
    //     this.name = name;
    //     this.age = age;
    // }
    // Father.prototype.f1 = function(){
    //     console.log(this.name,this.age);
    // }

    // 使用父级构造函数生成实例化对象
    // const obj = new Father('张三',18);

    // 定义一个空的子级构造函数 -- 空函数
    // function Son(){}

    // 在子级构造函数中,添加父级生成的实例化对象
    // Son.prototype = obj;

    // console.dir(Son);

    // 总结
    // 1,定义一个父级构造函数
    // 2,定义一个空的子级构造函数
    // 3,在子级构造函数的 prototype 中,添加父级构造函数,生成的实例化对象

    // 结果
    // 子级构造函数中,具有通过父级构造函数,添加的属性和方法

    // 原理:
    // 原型链: 构造函数,生成的实例化对象,实例化对象__proto__指向的是构造函数
    // 实例化对象---通过原型链---可以找到构造函数

    // 子级构造函数---需要找到父级构造函数   没办法直接建立关联
    // 子级构造函数---关联实例化对象---实例化对象关联父级构造函数
    // 通过 实例化对象 将两个 构造函数 使用原型链的方式,关联起来
    // 子级构造函数,可以调用父级构造函数中,定义的属性和方法

    // 属性是定义在实例化对象中的属性
    // 方法是定义在父级构造函数中的方法


    // 借用构造函数继承
    // 主要是继承属性,不继承方法

    // 


    // 父级构造函数
    // function Father(name,age){
    //     this.name = name;
    //     this.age = age;
    // }
    // Father.prototype.f1 = function(){
    //     console.log(this.name,this.age);
    // }  
    
    // const objF = new Father('lili' , 20)

    // function Son(sex){
        // 调用 父级构造函数 父级构造函数的this,默认执行的是父级构造函数生成的实例化对象
        // 在子级构造函数中,this应该执行的是子级构造函数生成的实例化对象 ojbS
        // 使用 call 语法 来改变Father() 构造函数,this 的指向
        // 让 Father() 执行是 Son() 的指向,也就是 设定 Father() 的this 和 Son() 的 this 是同一个this
        // 当前在 Son() 中 this 就是 Son() 的this , 将 this 设定为 call() 的第一个参数,就是设定 Father() 的this 就是 Son() 的this
        // 之后的两个实参,是Father()本身执行时,应该输入的实参
    //     Father.call(this, '张三' , 18);
    //     // 子级自定义属性
    //     this.sex = sex;
    // }
    // 自己构造函数,生成的实例化对象,就有两个从父级继承的属性
    // name,age,通过 call 从父级继承来,只要输入一个sex的实参就可以了
    // const objS = new Son('男');
    // console.log(objS);

// 所谓的组合继承,就是原型继承和借用构造函数继承,结合使用

    // 父级构造函数
    function Father(name,age){
        this.name = name;
        this.age = age;
    }
    Father.prototype.f1 = function(){
        console.log(this.name,this.age);
    }  

    // 通过父级构造函数,生成实例化对象
    const objF = new Father('张三',18);

    // 定义子级构造函数
    function Son(sex){
        // 通过call语法,设定 父级构造函数Father()的this为子级构造函数Son()的this
        // 并且定义 父级构造函数Father() 原有形参赋值实参
        Father.call( this , '李四' , 20);
        // 自定义的子级构造函数的属性
        this.sex = sex;
        
    }

    // 在子级构造函数的 prototype 中,添加父级构造函数生成的实例化对象
    Son.prototype = objF;
    
    // 使用子级构造函数,定义实例化对象
    const objS = new Son('男');

    console.log(objS);

// 总结

    // ES6
    //   1,有两个关键词
    //      extends 指定继承的父级
    //      在构造器constructor 中使用的 super 指定属性从父级继承
    //   2,属性可以都从父级继承而来
    //     从父级继承属性,自定义数值数据
    //     自定义属性和属性值
    //   3,父级方法一定会继承,也可以自定义方法




    // ES5
    //   1,原型继承
    //      定义父级构造函数
    //      定义子级空构造函数
    //      在子级 prototype 中 添加父级构造函数生成的实例化对象
    //      原理 : 通过 实例化对象 将两个 构造函数 通过 原型链 关联起来
    //      子级的属性是 实例化对象的属性
    //      子级的方法是 父级构造函数的方法

    //  2,借用构造函数继承
    //      只能继承属性不能继承方法
    //      通过 call函数 来改变父级构造函数的的this 指向
    //      让父级 构造函数的this指向,是子级构造函数的this指向
    //      父级构造函数,属性,也就是变成了子级构造函数的属性

    //  3,组合继承
    //      将 原型继承和 结构构造函数继承 组合在一起使用
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值