JavaScript继承的6种方法

JavaScript继承
六种继承:

  1. 原型链继承
  2. 构造继承
  3. 实例继承
  4. 拷贝继承
  5. 组合继承
  6. 寄生组合继承

继承则必须有父类,子类继承父类的属性和方法。

一、原型链继承

1、什么是原型链?
由外到内通过__proto__属性连接所形成的链式即为原型链。
原型链继承是通过prototype属性实现继承。
2、原型链继承的特点
实例可继承的属性有:实例的构造函数的属性,父类构造函数属性,父类原型的属性。
3、原型链继承的缺点
(1)不能继承子类的原型属性和方法;
(2)只能进行单继承,不能多继承;
(3)继承之后,原型对象上的属性全是共享;
(4)子类不能直接向父类传递参数。
4、实现

//父类
    function Person(a) {
        this.name = a;
        this.age = null;
        this.sex = "男";
        this.sleep = function () {
            return "睡觉";
        }
    }
    Person.prototype.height = 100;
//子类
    function Child() {
        this.job = null;
    }

    Child.prototype.eat = function () {
        return "吃饭";
    }
    var child = new Child();
    var child1 = new Child();
    console.log(child, child1);
    console.log(child  instanceof  Child); //true
    console.log(child  instanceof Person); //true

二、构造继承

构造继承通过使用call和apply来实现继承。
1、构造继承的优点
(1)可以实现多继承;
(2)可以向父类传递参数。

2、构造继承的缺点
(1)构造继承无法继承父类的原型属性和方法;
(2)子类的实例是本身不是父类。

3、实现

 //父类
 function Animal() {
        this.name = arguments[0];
        this.sleep = function () {
            return "睡觉";
        }
    }
    Animal.prototype.color = null;
//父类
function Type() {
        this.type = arguments[0];
    }
//子类
    function Dog(n, s, t) {
        this.sex = s;
        this.eat = function () {
            return "吃饭";
        }
        //写构造继承
        Animal.call(this, n);
        Type.apply(this, [t]);

    }
    Dog.prototype = {
        constructor: Dog,
        sleep: function () {

        }
    }

    var dog = new Dog("小花", "公", "犬科");
    console.log(dog);
    console.log(dog instanceof  Dog);//true

call(this,arg1,arg2) ;当后面参数个数确定时用call,参数之间用逗号连接。
apply(this,[arg1,arg2]);当后面参数个数不确定时用apply,参数通过数组形式输入。

三、实例继承

1、实例继承:
在子类内部直接构造父类的实例,即直接new父类。
2、实例继承的优点
(1)不限制调用方式;
(2)可以向父类传递参数。
3、实例继承的缺点
(1)不能实现多继承;
(2)不能拿到子类构造属性和方法;
(3)子类的实例不是本身而是父类。
4、实现

 //父类
 function Person(n,s){
        this.name=n;
        this.sex=s;
        this.sleep=function (){
            return "睡觉";
        }
    }
//子类
function Child(n,s){
        this.eat=function (){

        }
        return new Person(n,s);
    }

    //子类实例有两种写法
    var child=Child("小米","男");
    console.log(child);
    var child1=new Child("小米","男");
    console.log(child1);
    //子类对象的实例
    console.log(child instanceof  Child);//false
    console.log(child instanceof  Person);//true

四、拷贝继承

1、拷贝继承:
将父类里的方法和属性拷贝给子类。
2、拷贝继承的优点
(1)支持多继承;
(2)子类对象实例是本身不是父类;
(3)可以向父类传递参数。
3、拷贝继承的缺点
在继承时,不断的new,容易占内存。
4、实现

//父类    
function Animale(){
        this.name=arguments[0];
        this.sleep=function (){
            return "睡觉";
        }
    }
//父类
function Type(){
        this.type=arguments[0];
    }

//子类
function Cat(n,s,t){
        this.sex=s;
        this.eat=function (){
            return "吃饭";
        }
        //实例化父类对象
        var animale=new Animale(n);
        for(var key in animale)
        {
            Cat.prototype[key]=animale[key];
        }
        var type=new Type(t);
        for(var key in type)
        {
            Cat.prototype[key]=type[key];
        }

    }

    var cat=new Cat("小花","公","猫科");
    console.log(cat);
    //子类对象的实例是本身,不是父类
    console.log(cat instanceof  Cat);//true
    console.log(cat instanceof  Animale);//false
    console.log(cat instanceof  Type);//false

五、组合继承

1、组合继承
将原型链和构造函数的技术组合在一块,相互弥补双方的缺点。
2、组合继承的优点
(1)子类的实例既是本身也是父类;
(2)可以实现多继承;
(3)可以向父类传递参数;
(4)每个新实例引入的构造函数属性是私有的,没有实现原型对象属性的共享。
3、组合继承的缺点
调用了两次父类构造函数,子类的构造函数会代替原型上的那个父类构造函数。
4、实现

 //父类   
function Person(n){
        this.name=n;
        this.eat=function (){
            return this.name+"吃饭";
        }
    }
    Person.prototype={
        constructor:Person,
        color:null
    }
//子类
function Child(a,s,n){
        this.age=a;
        this.sex=s;
        this.sleep=function (){
            return "睡觉";
        }
        Person.call(this,n); //只能获取到父类的属性和方法,拿不到原型属性和方法
    }
    Child.prototype=new Person();//注意这  这里没传值,"花花");
    console.log(child.eat());
    var child1=new Child(12,"女","小红");
    console.log(child1);
    
    console.log(child instanceof Child);//true
    console.log(child instanceof Person);//true

六、寄生组合继承

1、寄生组合继承
寄生:在函数内返回对象然后调用。处理组合继承的缺点。
2、寄生组合继承的特点
避免调用两次父类的构造函数。
3、寄生组合继承的原理
原理:将父类的原型对象给一个空对象的prototype,再把空对象和子类的原型对象关联。
4、实现

//父类
function Person(){
        this.name=null;
        this.sleep=function (){
            return this.name+"睡觉";
        }
    }

    Person.prototype={
        constructor:Person,
        color:null
    }
//子类
function Child(){
        this.age=null;
        this.eat=function (){
            return this.name+"吃饭";
        }
        Person.call(this);
    }

    //开始寄生
    (function (){
        var fn=function (){};
        fn.prototype=Person.prototype;
        Child.prototype=new fn();
    })();

    var child=new Child();
    console.log(child);

    console.log(child instanceof Child);//true
    console.log(child instanceof Person);//true
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值