js继承

109 阅读1分钟

构造函数绑定实现继承

拷贝继承

利用空对象作为中介

原型链继承实例化对象

原型链继承直接继承原型

通过call()或apply()方法 -->

 // let obj1 = {
        //     a:'tom'
        // }
        // let obj2 = {
        //     a:'jack'
        // }
        // function f(car,house){
        //     console.log('this指向',this); 
        //     console.log(car,house);
        //     return this.a;
        // }
        // console.log( window.f() ); /* this=>window */

        /* call 和 apply 是用来改变this指向的 */

        /* call和apply都可以理解为是函数自身的方法
        第一个参数代表了 接下来this所代表的对象 */
        /* f.call(obj1) 会执行f这个方法 */
        // console.log( f.call(obj1) ) /* this=>obj1 */
        // console.log( f.call(obj2) ) /* this=>obj2 */

        // console.log( f.apply(obj1) ) /* this=>obj1 */
        // console.log( f.apply(obj2) ) /* this=>obj2 */
        

call和apply的区别

使用call方法来传参 一个一个的传参

console.log( f.call(obj1,'bmw','tangc') ) /* this=>obj1

使用apply方法来传参 需要传一个数组 数组里面的第一个就对应了f函数里面的 第一个参数,数组里面的第二个就对应了f函数里面的 第二个参数

console.log( f.apply(obj1,['bmw','tangc']) )

组合继承

也叫伪经典继承 将原型链继承和构造函数继承组合在一块 原型链实现对原型属性和方法的继承 借用构造函数实现对实例属性的继承 -->

  // function Person(){
        //     /* 实例属性 */
        //     this.head = 1;
        //     this.foot = 2;
        // }

        // /* 原型属性和方法 */
        // Person.prototype.weight = '70kg';
        // Person.prototype.eat = function(){
        //     console.log('我会吃饭');
        // }
        // function Student(){
        //     /* 借用构造函数实现对实例属性的继承 */
        //     Person.call(this)
        // }
        // /* 原型链实现对原型属性和方法的继承 */
        // Student.prototype = new Person()
        // Student.prototype.contructor = Student;
        // let stu1 = new Student();
        // console.log(stu1);
        // console.log(stu1.weight);
        // stu1.eat();

        /* 
            父类 Car lunzi 4个 原型上有run方法打印 
            ${this.name} 我有4个轮子 会跑赛道
            子类 Bc 自己有name 通过传参获得 
            继承 实例属性 lunzi 和 原型方法run
            要求 用子类的方法 打印出  例如 : 奔驰 有 4 个轮子 会跑赛道
            使用组合继承的方法
        */
        function Car(){
            this.lunzi = 4;
        }
        Car.prototype.run = function (){
            document.write(`
                ${this.name} 我有${this.lunzi}个轮子 会跑赛道
            `);
        }
        function Bc(name){
            Car.call(this)
            this.name = name;
        }
        Bc.prototype = new Car();
        Bc.prototype.constructor = Bc;

        let bc1 = new Bc('奔驰')
        console.log(bc1);
        bc1.run();

 <!-- 在子类的内部调用父类的方法
    通过call()或apply()方法 -->
    <script>
        // function Person(){
        //     this.foot = 2
        // }
        // function Student(color,price){
        //     Person.call(this)
        // }
        // console.log( new Student('白色','100w') );

        /* 
            父类 Car lunzi 4个
            子类 name price 是通过传参获得实际的值
            方法 打印出  例如 : 奔驰 100w 有 4 个轮子(从父类继承)
            使用call 来实现继承
        */
       /* 父类 gang (几缸 例如:3缸 4缸 gang需要传参) 
       bsx(变速箱 例如:at变速箱 cvt变速箱 双离合变速箱 bsx需要传参) */
       /* 在子类print中 打印出 汽车名--价格--几个轮子--几缸发动机--什么变速箱 */
       /* 两种方式 分别使用call 和 apply */
       function Car(gang,bsx){
           this.lunzi = 4;
           this.gang = gang;
           this.bsx = bsx;
       }
       function Bc(name,price,gang,bsx){
           /* 把子类的this传给父类
           使用call来改变this指向,把父类中的this指向子类 */
        //    Car.call(this,gang,bsx);
           Car.apply(this,[gang,bsx])
           this.name = name;
           this.price = price;
           this.print = function (){
                document.write(`
                    ${this.name}--${this.price}--${this.lunzi}个轮子--${this.gang}--${this.bsx}
                `);
           }
       }
       let bc1 = new Bc('奔驰E300','55W','4缸','9AT变速箱');
       bc1.print();
       console.log(bc1);