当前位置: 移动技术网 > IT编程>开发语言>JavaScript > JS的几种继承方式介绍

JS的几种继承方式介绍

2018年10月30日  | 移动技术网IT编程  | 我要评论

原型链继承

当我们每创建一个函数时,该函数都会自带一个prototype属性,该属性会指向另一个对象,指向的这个对象就是该函数的原型对象。原型对象中又有一个指向构造函数的属性。通过new 构造函数的实例会指向原型对象。通过该特性,可以通过原型链实现继承。

1   //定义父类
2   function parent(){
3       this.property='超类';
4   }
5   parent.prototype.constructor=parent;
6   parent.prototype.getvalue=function(){
7       return this.property;
8   }
9   //定义子类
10  function son(){
11      this.property=false;
12  }
13  //通过原型继承parent
14  son.prototype=new parent();
15  son.prototype.constructor=son;
16  //在子类重写父类方法或添加新方法时,重写的方法和新添加方法的代码需要放在继承语句之后。
17  //重写父类的方法
18  son.prototype.getvalue=function(){
19      console.log('重写的getvalue方法');
20  }
21  //新添加的方法
22  son.prototype.showmsg=function(){
23      console.log('新添加的方法');
24  }
25  var s=new son();
26  s.getvalue();   //重写的getvalue方法
27  s.showmsg();    //新添加的方法

需要注意的一点是,在通过原型链继承时,不能使用对象字面量的方式给原型对象方法,因为这样会重写掉原型链(对象字面量都是object的实例)。

1       function parent(){
2           this.attr='test attr';
3       }
4       function son(){}
5       //原型链继承parent
6       son.prototype=new parent();
7           //通过对象字面量给原型添加方法
8       son.prototype={
8           showattr=function(){
10              console.log(this.attr);
11          }
12      };
13
14      var s=new son();
15      s.showattr();   //报错
原型链的问题

当通过原型链进行继承时,原来父类型的引用类型的属性会变成子类型原型对象的实例。即该属性会被子类型实例的公共属性。

1   function super(){
2       this.colors=['blue','red'];
3   }
4
5   function sub(){}
6   sub.prototype=new super();
7   var sub1=new sub();
8   sub1.colors.push('green');
9   console.log(sub1.colors);  //["blue", "red", "green"]
10  var sub2=new sub();
11  console.log(sub2.colors);  //["blue", "red", "green"]

构造函数继承

构造函数继承可以解决原型链继承的问题。

在子类型构造函数中使用call和apply方法调用父类型的构造方法实现继承

1   function super(name,age){
2       this.friends=['kkk','abc'];
3       this.name=name;
4       this.age=age;
5   }
6
7   function sub(){
8       //super.call(this);
9       super.apply(this,arguments);
10  }
11  var s=new sub('aaa',22);
12  s.friends.push('new');
13  console.log(s.friends);  //["kkk", "abc", "new"]
14  console.log(s.name);  //aaa
15  console.log(s.age);   //22
16
17  var s1=new sub();
18  console.log(s1.friends);  // ["kkk", "abc"]

由s.friends和s1.friends返回的结果可知,原型链继承的问题可以由构造方法继承方法解决,但这种继承方法也存在问题:

构造函数继承的问题

由于所有的属性和方法都在构造函数上,每创建一个实例,相同功能的方法却同时占不同的内存,造成内存浪费。

组合继承

组合继承、即由原型链继承和构造函数继承组合在一起实现继承。该继承方式简单来说就是使用原型链继承原型的方法、通过构造函数继承方式继承属性。

1   //组合继承
2   function super(name,age){
3       this.name=name;
4       this.age=age;
5       this.friends=['aaa','bbb'];
6   }
7   super.prototype={
8       constructor:super,
9       getmsg:function(){
10          console.log(this.name+' '+this.age)
11      }
12  }
13  
14  function sub(name,age,hobby){
15      //属性通过构造方法继承
16      //super.call(this,name,age);
17      super.apply(this,[name,age]);
18
19      //补充:为了避免父类的属性重写子类新增的属性或重写子类的属性,应将继承语句放在子类的第一行。
20      this.hobby=hobby;
21  }
22  //通过原型链继承方法。
23  sub.prototype=new super();
24  sub.prototype.constructor=sub;
25  sub.prototype.getsubmsg=function(){
26      console.log(this.name+' '+this.age+' '+this.hobby+' '+this.friends);
27  }
28  var s=new sub('kevin',22,'篮球');
29  s.friends.push('ccc');
30  s.getmsg(); //kevin 22
31  s.getsubmsg();  //kevin 22 篮球 aaa,bbb,ccc
32  
33  var s1=new sub('paul',28,'电影');
34  s1.getmsg();    //paul 28
35  s1.getsubmsg(); //paul 28 电影 aaa,bbb

由代码结果可知,组合继承方式融合了原型链继承和构造方法继承的优点,又同时避开了它们的缺点。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网