JavaScript实现继承的几种方式

这篇文章中,介绍了原型链继承的情形,事实上,JavaScript虽没有给出继承的关键字,但是我们依然能够拿出一些好办法实现。

 

1、原型链继承:

Js代码  收藏代码

  1. var Base = function()  
  2. {  
  3.     this.level = 1;  
  4.     this.name = “base”;  
  5.     this.toString = function(){  
  6.         return “base”;  
  7.     };  
  8. };  
  9. Base.CONSTANT = “constant”;  
  10.   
  11. var Sub = function()  
  12. {  
  13. };  
  14. Sub.prototype = new Base();  
  15. Sub.prototype.name = “sub”;  

 

优点:从instanceof关键字来看,实例既是父类的实例,又是子类的实例,看起来似乎是最纯粹的继承。

缺点:子类区别于父类的属性和方法,必须在Sub.prototype = new Base();这样的语句之后分别执行,无法被包装到Sub这个构造器里面去。例如:Sub.prototype.name = “sub”;无法实现多重继承。

 

 

2、构造继承:

Js代码  收藏代码

  1. var Base = function()  
  2. {  
  3.     this.level = 1;  
  4.     this.name = “base”;  
  5.     this.toString = function(){  
  6.         return “base”;  
  7.     };  
  8. };  
  9. Base.CONSTANT = “constant”;  
  10.   
  11. var Sub = function()  
  12. {  
  13.     Base.call(this);  
  14.     this.name = “sub”;  
  15. };  

优点:可以实现多重继承,可以把子类特有的属性设置放在构造器内部。

缺点:使用instanceof发现,对象不是父类的实例。

 

 

3、实例继承:

Js代码  收藏代码

  1. var Base = function()  
  2. {  
  3.     this.level = 1;  
  4.     this.name = “base”;  
  5.     this.toString = function(){  
  6.         return “base”;  
  7.     };  
  8. };  
  9. Base.CONSTANT = “constant”;  
  10.   
  11. var Sub = function()  
  12. {  
  13.     var instance = new Base();  
  14.     instance.name = “sub”;  
  15.     return instance;  
  16. };  

优点:是父类的对象,并且使用new构造对象和不使用new构造对象,都可以获得相同的效果。

缺点:生成的对象实质仅仅是父类的实例,并非子类的对象;不支持多继承。

 

 

4、拷贝继承:

Js代码  收藏代码

  1. var Base = function()  
  2. {  
  3.     this.level = 1;  
  4.     this.name = “base”;  
  5.     this.toString = function(){  
  6.         return “base”;  
  7.     };  
  8. };  
  9. Base.CONSTANT = “constant”;  
  10.   
  11. var Sub = function()  
  12. {  
  13.     var base = new Base();  
  14.     for(var i in base)  
  15.         Sub.prototype[i] = base[i];  
  16.     Sub.prototype[“name”] = “sub”;  
  17. };  

优点:支持多继承。

缺点:效率较低;无法获取父类不可枚举的方法。

 

 

这几种形式各有特点,仅就我提供的代码而言,满足下面的表格:

 

instanceof父类 instanceof子类 子类constructor 不可枚举方法的继承 多继承可实现
原型链继承 TRUE TRUE FALSE TRUE FALSE
构造继承 FALSE TRUE TRUE TRUE TRUE
实例继承 TRUE FALSE FALSE TRUE FALSE
拷贝继承 FALSE TRUE TRUE FALSE TRUE

 

—————————————————————————————————————————

 

2012-1-10:补充,如果我们不需要类继承,只需要对象继承,对于支持 ECMAScript 5 的浏览器来说,还可以用Object.create方法来实现:

Js代码  收藏代码

  1. var Base = function()  
  2. {  
  3.     this.level = 1;  
  4.     this.name = “base”;  
  5.     this.toString = function(){  
  6.         return “base”;  
  7.     };  
  8. };  
  9. Base.CONSTANT = “constant”;  
  10.   
  11. var sub = Object.create(new Base());  
  12. sub.name = “sub”;  

 

发表评论