在JavaScript面向对象编程中使用继承(2)

简介:
  昨天扔了一堆JavaScript类'继承'的代码,这些代码其实并不是所有的都能正常的执行。不是我不原意写出都能好好执行的继承类代码,而是这些方法本身就各自有自己的优缺点。下面我分别说它们的原理和使用时注意事项。

    构造继承法的原理:

    构造继承法关键代码是 function ArrayList01()中的:
  this.base = CollectionBase;
   this.base(); 

    这里的base不是C#派生类中的base那个概念,完全就是一个任意的JavaScript变量名。调用 this.base();其实就是执行的CollectionBase();,不过 不是 new CollectionBase();哦!没有 new基类那么怎么得到CollectionBase中的方法和属性呢?这里使用了 this作用域的一个hack,'欺骗'了脚本引擎。当我们从类ArrayList01的构造函数中调用 this.base();时,在基类CollectionBase中的 this就是ArrayList01的一个实例,于是执行CollectionBase的构造函数,就动态的把基类的成员和方法attach到ArrayList01实例中了。构造法的问题也就是从这里产生了,注意哦。

    构造继承法的缺陷:

    第一个问题,关键是出在上面那两段代码上,因为始终没有 new基类呀。这样带来的问题就是不能把基类CollectionBase中的原型属性和方法attach到ArrayList01的实例中,啊,这样还算是什么继承啊?! 所以在 上篇文章中我为了不改动CollectionBase类,而单独为其实现了一个Add()方法(只是为了统一示例代码而已)。解决这个缺陷的方法其实也很简单,就是要求基类不能使用prototype来导入属性和方法,而要把所有的属性和方法都写到构造函数中去,分别是: this.Attribute = ...; 和 this.Method = function() {...};这种形式。
    第二个问题,是 this.base = CollectionBase;和 this.base();必须写在派生类构造函数的最开头(不是一定要是第一行和第二行,而是它们的前面不能有 this.xxx这种定义为ArrayList01导入的任何属性或方法),因为调用 this.base();时会向 this(ArrayList01的一个实例)中注入基类的属性和方法,如果基类中有和 this中已导入的属性和方法重名的,就自动覆盖掉子类中的方法。
    第三个问题,是子类也不能使用prototype来导入属性和方法,这和问题二中的重名覆盖道理一样,由于prototype导入的属性和方法在子类一 new的时候就生成了,所以也存在和基类重名而被覆盖的潜在错误威胁。解决办法,和基类编写规则一样不要使用prototype,并且将子类的属性和方法定义代码放在导入继承的代码( this.base = CollectionBase; this.base();)之后。

    构造继承法的示例:   
< script  language ="JavaScript" >
document.write('构造继承法:
< br > ');
var  arrayList11  =   new  ArrayList01();
arrayList11.Add('a');
arrayList11.Add('b');
arrayList11.foo();
var  arrayList12  =   new  ArrayList01();
arrayList12.Add('a');
arrayList12.Add('b');
arrayList12.Add('c');
arrayList12.foo();
</ script >

    示例运行结果为:
构造继承法:
[class ArrayList01]: 2: a,b
[class ArrayList01]: 3: a,b,c

    小结一下:JavaScript的构造继承法其实看起来还是比较直观的,因为子类构造函数中有对基类构造函数的调用,似乎在语法上还比较容易被接受。可是由于没有 new基类,带来了不能获得prototype导入的属性和方法的缺陷。解决这个缺陷的方法虽然不难,可是由此而给基类编写限制一个凌驾于JavaScript语法规范的规则,可操作性不是很好。子类也不能利用prototype特性来导入属性和方法,会与基类之间存在潜在的重名覆盖问题。所以对于复杂的基类,不推荐这种继承方法,因为类复杂了,使用prototype可以规范类代码,使类的定义看起来比较的舒服

    应用场景:小规模类之间的继承,基类和子类的属性方法在5-8个。还有就是以构造函数中赋值方式导入类的属性和方法,而不用prototype导入的类编写习惯的时候。


本文转自博客园鸟食轩的博客,原文链接:http://www.cnblogs.com/birdshome/,如需转载请自行联系原博主。

目录
相关文章
|
9天前
|
JavaScript 前端开发
Javascript如何实现继承?
【10月更文挑战第24天】JavaScript 中实现继承的方式有很多种,每种方式都有其优缺点和适用场景。在实际开发中,我们需要根据具体的需求和情况选择合适的继承方式,以实现代码的复用和扩展。
|
3天前
|
JavaScript 前端开发
如何使用原型链继承实现 JavaScript 继承?
【10月更文挑战第22天】使用原型链继承可以实现JavaScript中的继承关系,但需要注意其共享性、查找效率以及参数传递等问题,根据具体的应用场景合理地选择和使用继承方式,以满足代码的复用性和可维护性要求。
|
3天前
|
JavaScript 前端开发 开发者
js实现继承怎么实现
【10月更文挑战第26天】每种方式都有其优缺点和适用场景,开发者可以根据具体的需求和项目情况选择合适的继承方式来实现代码的复用和扩展。
15 1
|
2月前
|
自然语言处理 JavaScript 前端开发
一文梳理JavaScript中常见的七大继承方案
该文章系统地概述了JavaScript中七种常见的继承模式,包括原型链继承、构造函数继承、组合继承、原型式继承、寄生式继承、寄生组合继承等,并探讨了每种模式的实现方式及其优缺点。
一文梳理JavaScript中常见的七大继承方案
|
29天前
|
JavaScript 前端开发 Java
JavaScript中的面向对象编程(OOP) - 终极指南
本文介绍了 JavaScript 的面向对象编程 (OOP) 概念,包括继承、多态、封装和抽象等关键要素,并通过代码示例帮助开发者理解和应用 OOP 思维。
35 5
|
2月前
|
JavaScript 前端开发
js之class继承|27
js之class继承|27
|
2月前
|
JavaScript 前端开发 Java
js面向对象编程|24
js面向对象编程|24
|
2月前
|
JSON JavaScript 前端开发
js原型继承|26
js原型继承|26
|
2月前
|
JavaScript 前端开发 开发者
JavaScript 类继承
JavaScript 类继承
19 1
|
2月前
|
JavaScript 前端开发
JS的几种继承方式
JavaScript中的几种继承方式视频。
14 0