面试--js实现继承的几种方式

基于原型的继承

  function father() {
        this.faName = 'father';
        this.names=['11','22']
    }
    father.prototype.getfaName = function() {
        console.log(this.faName);
    };
    function child() {
        this.chName = 'child';
    }
    child.prototype = new father();
    child.prototype.constructor = child;
    child.prototype.getchName = function() {
        console.log(this.chName);
    };
    var c1=new child();
    c1.names.push("sasa");
    var c2=new child();
    console.log(c2.names)   //原型上的names属性被共享了 不是我们所需要的

这种继承会有如下的缺点:
1、如果父类包含有引用类型的属性 所有的子类就会共享这个属性。
2、在创建子类的实例时 不能向父类的构造函数传递参数

组合式继承

原型继承+构造函数的继承

 function father(name) {
        this.faName = 'father';
    }
    father.prototype.getfaName = function() {
        console.log(this.faName);
    };
    function child(args) {
        this.chName = 'child';
        father.apply(this,[]); //第二次调用父类构造函数
    }
    child.prototype = new father(); //第一次调用父类构造函数
    child.prototype.constructor = child;
    child.prototype.getchName = function() {
        console.log(this.chName);
    };

子类继承父类的属性,一组在子类实例上,一组在子类原型上(在子类原型上创建不必要的多余的属性)

寄生组合实现继承

 function father(name) {
        this.faName = 'father';
    }
    father.prototype.getfaName = function() {
        console.log(this.faName);
    };
    function object(o) {    //创建一个原型为o的新对象
        function F() {};
        F.prototype = o;
        return new F();
    }
    /**
     * 通用方法实现子类继承父类
     * @param  {function} child  子类构造函数
     * @param  {function} father 被继承的父类构造函数
     */
    function inheritPrototype(child, father) {
        var prototype = object(father.prototype); //创建一个指定原型的对象
        prototype.constructor = child; //增强对象
        child.prototype = prototype; //子类的原型等于该对象
    }
    function child(args) {
        this.chName = 'child';
        father.apply(this,[]);   //调用父类的构造函数可以通过args传递参数
    }
    inheritPrototype(child, father); //子类的原型等于new 空函数(), 而new 空函数()出来的对象的原型等于父类的原型
    child.prototype.getchName = function() {
        console.log(this.chName);
    };
    console.log( child.prototype.isPrototypeOf(new child()) ); //true
    console.log(new child() instanceof child); //true

优点:1.只调用一次父类的构造函数,避免了在子类原型上创建不必要的,多余的属性

  2.原型链保持不变 

es6实现的继承

   class father{
        constructor(name){
            this.name=name
            this.names=[1,2,3]
        }
        getname(){
            console.log(this.name);
        }
    }
    class child extends father{
        constructor(name){
            super(name);
        }
        sayHello(){
            console.log("sayHello");
        }
        static hh(){
            console.log("hh")
        }
    }
    var cc=new child("juanjuan");
    cc.sayHello();
    cc.getname();  //juanjuan
    child.hh();  //hh
    cc.names.push("wqwq");
    var c1=new child("sasasa");
    console.log(c1.names)  //[1,2,3]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值