在很久很久以前,我发布了一篇博文探讨了如何用JavaScript实现简单的继承,详见 [ JavaScript面向对象编程(1) :继承 ] .这种方式对我来说直观而容易理解,有效防止侧漏又不伤手,让我整夜安睡,所以我一直在用它,嘿,还真对得起咱这张脸.
但它有一个很大的缺点: 所有的方法变量都是暴露在外的,都能随意访问,这一点都不符合面相对象编程的"封装"的要求嘛!作为追求完美的我,可以容忍goto语句,可以容忍i,j,k,l,mm,hhh这样的变量名称,可以容忍一个函数包含3000多行代码,可以容忍<爱情买卖>,可以容忍铺天盖地的"给力",但是!我!怎么能!容忍!OOP的三大基本特征遭到亵渎?! 不知道OOP的三大基本特征? 不知道? 真不知道? ..........那你来这儿干什么?
所以后来我又构思了一种方案,可以解决上面这个问题.
这个新方案使用了闭包技术(你又不知道闭包?.....吐血中...), 有以下特性:
1 跟前一个方案一样,在在"构造函数"(嗯,就是你自己为了定义一个对象而写的那个函数啦---怎么这么拗口)第一行必须调用工具函数Class()来添加对继承,重载以及封装的支持.当然这个函数的代码与第一个方案是不同的,等会儿我会给出这个函数的代码
2 用public.函数名=function(...){...}的形式来定义"公有函数",公有函数就是...,不说了,你懂得.
3 用局部变量方式定义"私有成员",这里加上引号是指并不是真正意义上的私有成员,只是与私有成员类似,外部使用者不可见.
4 公有函数可以直接用名称调用"私有成员",但必须用this.函数名来调用其它公有函数.
5 "私有函数"可以直接用名称调用"私有成员",但必须用public.函数名来调用公有函数.
6 父对象的公有函数可用父对象名_函数名的方式使用
7 最后必须用return NewInstance();来得到真正的对象的实例(我叫它接口,:p),等会儿我会给出函数NewInstance的代码.
8 生成实例时可以用new也可以不用.如
var myClass = new MyClass();
和
var myClass = MyClass();
都有效
可以看出4和5是这个方案的硬伤,曾经让我几乎要无情的抛弃这个方案.不过我已经对解决它们有了一些头绪,在不久的将来(就三五年吧)我会解决它们.
下面是最关键的函数Class和NewInstance的代码,从这两个函数可以看出,实际上我是在"构造函数"中创建了一个名叫public的局部对象,并把所有希望能够在外部访问的函数(包括父对象的)都添加到public,然后将public作为真正的对象的实例返回到外部,根据闭包原理"构造函数"中的局部变量和函数和public在同一个作用域,所以public的函数可以访问"构造函数"中的局部变量和函数,但其他外部函数和代码则不能.
下面是使用方法的示例代码