类的继承

https://www.cnblogs.com/sandraryan/

类的继承

要求构造函数首字母大写,便于区分构造函数和普通函数

编程过程中有一批数据有相同的属性和行为,为代码不冗余,让编程更有效率。将这些属性和行为封装起来,称为类(实际上还是函数)。

然后通过特殊方法调用函数,拿到返回值和具体的对象。

类为什么要继承

   A类和B类有相同的行为属性,单独封装代码冗余,产生了继承,讲共同的单独封装在一个C类中,通过代码让AB和C建立联系。

从A B中实例化的对象都能使用C的行为。就称AB类继承了C类。

例如 数组和字符串都有length indexOf等方法。

call apply

不是为继承而生,但过于强大而被用于继承。。

  var a = 'aaaaa';
        var tom = {
            name:'tom',
            run: function(){
                console.log(this.name + ' is running');
                // tom可以访问a
                // run能直接访问的只有tom里面的
            }
        };
        // run(); 掉的是window下的run(),并不存在
        tom.run();
        var jery = {
            name: 'jery',
            run: function(){
                console.log(this.name +' is running');
            }
        }
        jery.run();
        jery.run.call(tom);
     jert.run.apply(tom);

jery.run.call(tom); 调用的是jery的run,但是用了call(tom),使jery里的this指向变成tom

call apply是js为函数提供的函数;(就像push是为array提供的一样)

当一个函数调用了call和apply后,函数中的函数体代码会执行。

函数中this的指向会变成call 和apply的第一个参数(this指向)

如果调用了call apply的执行需要传参,传给call apply。

call接受函数挨个传递

apply接受以数组形式传递

 var jery = {
            name: 'jery',
            run: function(t,f){
                console.log(this.name +' is running by' + t + f );
            }
        }

        jery.run.call(tom,'leg1',' leg2');
        jery.run.apply(tom,['head1',' head2']);

 call apply实现继承

 function Animal(kind){
        this.kind = kind;
        this.speak = function(){
            console.log('i can speak');
        };
      }
    //   原型方法
    Animal.prototype.run = function(){
        console.log('animal');
    }
    // function Dog(name){
    //     var that = this;
    //     Animal.call(that,'doggy');
    //     this.name = name;
    // }
    // 简化代码
    function Dog(name){
        Animal.call(this, '柴柴');
        this.name = name;
    }
    var  d = new Dog('柴柴');
    console.log(d);

 call 和apply函数可以实现继承,但只能i继承父类的公有方法和共有属性,无法继承原型的方法和属性

拷贝继承

拷贝继承只能继承父类原型的方法和属性,因为只对prototype做了拷贝

原型赋值继承

原型赋值继承也可以实现继承效果

这种继承只能继承原型

这种继承其实是让子类的prototype和父类的prototype指向了同一存储空间。

如果继承后再对子类原型做操作,父类原型也会被改变。不推荐

原型继承的真正方式

function Animal(kind){
            this.kind = kind;
            this.speak = function(){
                console.log('speaking');
            };
        }

        Animal.prototype.run = function(){
            console.log('running');
        }

        Animal.prototype.speak = function(){};
        Animal.prototype.sleep = function(){};

        function Dog(name){
            this.name = name;

        }
     Dog.prototype = new Animal('狗');
     var d = new Dog('tom');
     console.log(d);
     console.log(d.kind);
     d.speak();
     d.run();

从父类中实例化出一个对象,赋值给子类的prototype,既能继承到共有属性和方法也能继承到原型

但会导致constructor指向型错误,需要重新设置子类的constructor的指向

constructor指向这个对象的构造函数

原型链

假如有四个类ABCD,B继承A, C继承B,D继承C,

从D中实例化出一个对象,这个对象的_proto_指向D的prototype

_proto_的_proto_指向C的prototype,以此类推

原型链的产生是因为形成了继承链

原文地址:https://www.cnblogs.com/sandraryan/p/11540751.html