Javascript系列:实现继承
2007-11-14 09:59
597 查看
本文描述了Javascript的一种继承机制实现方案。
关于Javascript的继承实现,已经有包括著名的prototype在内的N多种方案了。虽然这些方案都粉不错,但如果不好好深入学习一番,只能用其做个玩具。但是,龙生九种,种种不同,光是风格迥异的代码就已经看得人头大了,更惶论在有限的时间内细品其味了。小生天生懒散,且生平只爱读古典作品(就是 印刷品啦),因此上,虽久闻N多大名,但无缘识荆。现仗着有些开发经验,斗胆弄斧,出来卖弄一番,让大家贝戈戈笑啦。
既然不愿使用现有的方案,就只能从头发明轮子。不过这样也好,既能打造符合自己需要的架构,又能够更深入的了解和掌握javascript的特性,二者相辅相成,岂不妙哉?!就是辛苦一些。
(唉,没有身体优势,青春饭还真难吃呀。)
作为动态语言Javascript,既不完全OO,特别是不支持继承,其与OO有关的部分又与我们所熟悉的语言有很大的不同。因此,要实现继承,必须利用其语言特性和一些技巧来辅助,以达到曲径通幽的效果。这个曲径的基础就是进行拷贝,包括对prototype域和public域(挂在this下的属性和方法都是public)的拷贝。知易行难,也唯其这样,才能够更好了解和设计JS的继承机制。
在JS中要继承(也就是拷贝)某一个类,要注意拷贝的先后次序。小心的处理拷贝次序,就能够在继承的基础上实现重载。
先来看对象的实例化次序, prototype域最先被实例化,然后,随着语句的执行,public域和私有域被填充。由于public域或私有域可能会覆盖prototype域(重载),因此,应先拷贝父类的prototype域,然后是public域。在拷贝时要注意,本体已经有的属性和方法不能被覆盖。在拷贝过程中,由于prototype域先被拷贝,而添加到prototype域后,成员(属性或方法)就会出现在this域中,这一点尤其要注意。
一个继承拷贝的参考实现如下:
// 直接修改Object的原型,使所有对象都具有继承拷贝方法
Object.prototype.derive = function(derivedClass, parentClass)
{
for ( var i in parentClass.prototype ) //先拷贝原型
{
if ( derivedClass.prototype[i] == undefined ) // 只拷贝子类没有定义的原型
{
derivedClass.prototype[i] = parentClass.prototype[i];
}
}
// 要取得对象的public域,必须先实例化
// 因此会产生闭包
var _instance = new parentClass();
for (var i in _instance) // 获取public域
{
if ( this[i] == undefined ) // 只有本地没有重载的,才会拷贝
{
this[i] = _instance[i];
}
}
} // end of method derive()
在实际应用中的例子如下:
// 基类
function TBase()
{
this.myvar = 'I/'m member variable'; // 某个公开的成员变量
}
// 不会被重载的原型
TBase.prototype.func1 = function() { alert('I/'m func1'); }
// 将要被重载的原型
TBase.prototype.shouldBeOverrided = function() { alert('I/'m in TBase'); }
// 派生类
function TMyClass1()
{
this.derive(TMyClass1, TBase); // 继承拷贝!
}
// 属于派生类的方法
TMyClass1.prototype.func2 = function() { alert('I/'m func2'); }
// 重载的方法
TMyClass1.prototype.shouldBeOverrided = function() { alert('I/'m in TMyClass1'); }
var x = new TMyClass1();
x.func1(); // 调用TBase.func1
x.func2(); // 调用TMyClass1.func2
x.shouldBeOverrided(); // 调用被重载的shouldBeOverrided
拷贝次序将如下所示:
原型拷贝:
derive方法:本身已经有了(来自Object),不被拷贝
func1方法:本身没有这个方法,拷贝之
shouldBeOverrided:被重载的方法,拷贝之
public域拷贝:
shouldBeOverrided:不会被拷贝
func1:已经在原型拷贝中处理过了,不会被拷贝
derive:不会被拷贝
myvar:被拷贝
拷贝完成后的成员列表如下:
func2
derive
shouldBeOverrided
func1
myvar
至此,一个基本的继承机制就完成了。当然,这只是个基础,还有一些重要的问题,如成员变量的深层次拷贝,留至下一篇再讨论吧。
相关文章推荐
- [原]JavaScript必备知识系列-继承的实现方式
- JavaScript学习系列之深入原型链与继承的实现
- javascript面向对象系列第三篇——实现继承的3种形式
- 拖拽系列一、JavaScript实现简单的拖拽效果
- javascript 中面向对象实现 如何继承
- javascript实现数据结构与算法系列:栈 -- 顺序存储表示和链式表示及示例
- javascript中实现对象继承的五种方式详解
- Javascript实现继承
- javascript内部原理篇[javascript实现继承]
- JavaScript实现类的private、protected、public、static以及继承
- 转载:javascript 继承实现的一种方法
- javascript 面向对象(实现继承的几种方式)
- javascript 用函数实现继承详解
- 学习javascript面向对象 javascript实现继承的方式
- 学习javascript面向对象 javascript实现继承的方式
- JavaScript继承实现方式一览
- 详解Javascript的继承实现(二)
- [渣译文] 使用 MVC 5 的 EF6 Code First 入门 系列:为ASP.NET MVC应用程序实现继承
- javascript的继承实现
- [11] 使用 MVC 5 的 EF6 Code First 入门 系列:为ASP.NET MVC应用程序实现继承