面对这样的窘境——Crockford的方法出现问题、在互联网上没有找到符合要求的方法,我决定看看我自己是否可以发明一种可以满足要求的方法。
这花掉了我近一周的时间来使代码工作并满足各种情况,但我对它的工作情况很有信心,并且很快把它与framework集成在一起,TinWire的beta和beta2两个版本中都使用了这些“初级设计”的代码。
动态父类调用:
一次性支持代码:
运行示例:
//定义最顶级类
function Class() { }
Class.prototype.construct = function() {};
Class.__asMethod__ = function(func, superClass) {
return function() {
var currentSuperClass = this.$;
this.$ = superClass;
var ret = func.apply(this, arguments);
this.$ = currentSuperClass;
return ret;
};
};
Class.extend = function(def) {
var classDef = function() {
if (arguments[0] !== Class) { this.construct.apply(this, arguments); }
};
var proto = new this(Class);
var superClass = this.prototype;
for (var n in def) {
var item = def[n];
if (item instanceof Function) {
item = Class.__asMethod__(item, superClass);
}
proto[n] = item;
}
proto.$ = superClass;
classDef.prototype = proto;
//赋给这个新的子类同样的静态extend方法
classDef.extend = this.extend;
return classDef;
};
//Hey, 注意一下这个类的定义方式
//看上去比其它方式要清楚些
var BaseClass = Class.extend({
construct: function() { /* optional constructor method */ },
getName: function() {
return "BaseClass(" + this.getId() + ")";
},
getId: function() {
return 1;
}
});
var SubClass = BaseClass.extend({
getName: function() {
//调用BaseClass的getName()方法
return "SubClass(" + this.getId() + ") extends " +
this.$.getName.call(this);
},
getId: function() {
return 2;
}
});
var TopClass = SubClass.extend({
getName: function() {
//调用SubClass的getName()方法
return "TopClass(" + this.getId() + ") extends " +
this.$.getName.call(this);
},
getId: function() {
//this.getId()总是返回调用父类的getId()方法的返回值(2)
return this.$.getId.call(this);
}
});
//输出结果:"TopClass(2) extends SubClass(2) extends BaseClass(2)"
//一切都正确!
alert(new TopClass().getName());
这里是前面示例的,但是目前这种方式包括了通过“extend”方法实现的十分清晰的类定义模式和正确的父类调用语义。尤其是“extend”方法通过一个中间function封装了类定义中的每个方法,这个中间function在每次方法调用时首先把当前父类引用“$” 与正确的父类引用相互交换,然后把这个正确的父类引用传递给apply()进行方法调用,最后再将把当前父类引用“$” 与正确的父类引用交换回来。这种方式唯一的问题就是它需要一些中间function,它们会对性能产生不良影响。所以近来我重新审视了设计、完成了去掉了中间function了一种改良的方式。
更多内容请看PCdog.com--Ajax的WEB开发 Ajax基础教程 Ajax技术专题
