javascript-4

如果说这是递归调用呢?却并非那种函数自身对自身的直接或间接调用,而是调用一个函数却返回另一个函数,再调用返回的函数又会在其中产生新的返回函数。如果说是函数式编程中的高阶函数调用呢?这函数的嵌套阶数却是与类层次相关的不确定数,而每一个阶梯都有新生成的函数。
这可真是闭包中嵌套着闭包,貌似递归却又不是递归,是高阶函数却又高不可测。一旦整个对象创建完成,用过的内存状态都释放得干干净净,只得到一尘不染的新建对象。JavaScript玩到这样的境界,方显观音大士的法力!
下面就是是重写后的完美甘露模型代码:
http://www.leadzen.cn/Books/WuTouJavaScript/1/JS25.htm

javascript-4

javascript-4
<script type="text/javascript">
javascript-4


javascript-4
//定义类的语法甘露:Class()

javascript-4
//最后一个参数是JSON表示的类定义

javascript-4
//如果参数数量大于1个,则第一个参数是基类

javascript-4
//第一个和最后一个之间参数,将来可表示类实现的接口

javascript-4
//返回值是类,类是一个构造函数

javascript-4
function Class()

javascript-4

javascript-4

javascript-4
{

javascript-4
var aDefine = arguments[arguments.length-1]; //最后一个参数是类定义

javascript-4
if(!aDefine) return;

javascript-4
var aBase = arguments.length>1 ? arguments[0] : object; //解析基类

javascript-4


javascript-4

javascript-4
function prototype_()
javascript-4
{}; //构造prototype的临时函数,用于挂接原型链

javascript-4
prototype_.prototype = aBase.prototype; //准备传递prototype

javascript-4
var aPrototype = new prototype_(); //建立类要用的prototype

javascript-4


javascript-4
for(var member in aDefine) //复制类定义到当前类的prototype

javascript-4
if(member!="Create") //构造函数不用复制

javascript-4
aPrototype[member] = aDefine[member];

javascript-4


javascript-4
//根据是否继承特殊属性和性能情况,可分别注释掉下列的语句

javascript-4
if(aDefine.toString != Object.prototype.toString)

javascript-4
aPrototype.toString = aDefine.toString;

javascript-4
if(aDefine.toLocaleString != Object.prototype.toLocaleString)

javascript-4
aPrototype.toLocaleString = aDefine.toLocaleString;

javascript-4
if(aDefine.valueOf != Object.prototype.valueOf)

javascript-4
aPrototype.valueOf = aDefine.valueOf;

javascript-4


javascript-4
if(aDefine.Create) //若有构造函数

javascript-4
var aType = aDefine.Create //类型即为该构造函数

javascript-4
else //否则为默认构造函数

javascript-4
aType = function()

javascript-4

javascript-4

javascript-4
{

javascript-4
this.base.apply(this, arguments); //调用基类构造函数

javascript-4
};

javascript-4


javascript-4
aType.prototype = aPrototype; //设置类(构造函数)的prototype

javascript-4
aType.Base = aBase; //设置类型关系,便于追溯继承关系

javascript-4
aType.prototype.Type = aType; //为本类对象扩展一个Type属性

javascript-4
return aType; //返回构造函数作为类

javascript-4
};

javascript-4


javascript-4
//根类object定义:

javascript-4

javascript-4
function object()
javascript-4
{} //定义小写的object根类,用于实现最基础的方法等

javascript-4
object.prototype.isA = function(aType) //判断对象是否属于某类型

javascript-4

javascript-4

javascript-4
{

javascript-4
var self = this.Type;

javascript-4
while(self)

javascript-4

javascript-4

javascript-4
{

javascript-4
if(self == aType) return true;

javascript-4
self = self.Base;

javascript-4
};

javascript-4
return false;

javascript-4
};

javascript-4


javascript-4
object.prototype.base = function() //调用基类构造函数

javascript-4

javascript-4

javascript-4
{

javascript-4
var Base = this.Type.Base; //获取当前对象的基类

javascript-4
if(!Base.Base) //若基类已没有基类

javascript-4
Base.apply(this, arguments) //则直接调用基类构造函数

javascript-4
else //若基类还有基类

javascript-4

javascript-4

javascript-4
{

javascript-4
this.base = MakeBase(Base); //先覆写this.base

javascript-4
Base.apply(this, arguments); //再调用基类构造函数

javascript-4
delete this.base; //删除覆写的base属性

javascript-4
};

javascript-4
function MakeBase(Type) //包装基类构造函数

javascript-4

javascript-4

javascript-4
{

javascript-4
var Base = Type.Base;

javascript-4
if(!Base.Base) return Base; //基类已无基类,就无需包装

javascript-4
return function() //包装为引用临时变量Base的闭包函数

javascript-4

javascript-4

javascript-4
{

javascript-4
this.base = MakeBase(Base); //先覆写this.base

javascript-4
Base.apply(this, arguments); //再调用基类构造函数

javascript-4
};

javascript-4
};

javascript-4
};

javascript-4


javascript-4
//语法甘露的应用效果:

javascript-4
var Person = Class //默认派生自object基本类

javascript-4

javascript-4
(
javascript-4
{

javascript-4
Create: function(name, age)

javascript-4

javascript-4

javascript-4
{

javascript-4
this.base(); //调用上层构造函数

javascript-4
this.name = name;

javascript-4
this.age = age;

javascript-4
},

javascript-4
SayHello: function()

javascript-4

javascript-4

javascript-4
{

javascript-4
alert("Hello, I'm " + this.name + ", " + this.age + " years old.");

javascript-4
},

javascript-4
toString: function() //覆写toString方法

javascript-4

javascript-4

javascript-4
{

javascript-4
return this.name;

javascript-4
}

javascript-4
});

javascript-4


javascript-4
var Employee = Class(Person, //派生自Person类

javascript-4

javascript-4

javascript-4
{

javascript-4
Create: function(name, age, salary)

javascript-4

javascript-4

javascript-4
{

javascript-4
this.base(name, age); //调用基类的构造函数

javascript-4
this.salary = salary;

javascript-4
},

javascript-4
ShowMeTheMoney: function()

javascript-4

javascript-4

javascript-4
{

javascript-4
alert(this + " $" + this.salary); //这里直接引用this将隐式调用toString()

javascript-4
}

javascript-4
});

javascript-4


javascript-4
var BillGates = new Person("Bill Gates", 53);

javascript-4
var SteveJobs = new Employee("Steve Jobs", 53, 1234);

javascript-4
alert(BillGates); //这里将隐式调用覆写后的toString()方法

javascript-4
BillGates.SayHello();

javascript-4
SteveJobs.SayHello();

javascript-4
SteveJobs.ShowMeTheMoney();

javascript-4


javascript-4
var LittleBill = new BillGates.Type("Little Bill", 6); //用BillGate的类型建LittleBill

javascript-4
LittleBill.SayHello();

javascript-4


javascript-4
alert(BillGates.isA(Person)); //true

javascript-4
alert(BillGates.isA(Employee)); //false

javascript-4
alert(SteveJobs.isA(Person)); //true

javascript-4
</script>
当今的JavaScript世界里,各式各样的AJAX类库不断出现。同时,在开放Web API的大潮中,AJAX类库作为Web API最重要的形式,起着举足轻重的作用。这些AJAX类库是否方便引用,是否易于扩展,是否书写优雅,都成了衡量Web API质量的重要指标。
甘露模型基于JavaScript原型机制,用及其简单的Class()函数,构造了一个非常优雅的面向对象的类机制。事实上,我们完全可以在这个甘露模型的基础上打造相关的的AJAX类库,为开发人员提供简洁而优雅的Web API接口。
想必微软那些设计AJAX架构的工程师看到这个甘露模型时,肯定后悔没有早点把AJAX部门从美国搬到咱中国的观音庙来,错过了观音菩萨的点化。
当然,我们也只能是在代码的示例中,把Bill Gates当作对象玩玩,真要让他放弃上帝转而皈依我佛肯定是不容易的,机缘未到啊!如果哪天你在微软新出的AJAX类库中看到这种甘露模型,那才是真正的缘分!
Tags: 

延伸阅读

最新评论

发表评论