当前页面: 开发资料首页 → Java 专题 → 解开JavaScript生命的达芬奇密码
摘要: 解开JavaScript生命的达芬奇密码
// 提前写好的JavaScript Class定义和继承
// 当然,这种代码很丑陋,散发着代码的坏味道。
function BaseClass() {
//BaseClass constructor code goes here
}
BaseClass.prototype.getName = function() {
return "BaseClass";
}
function SubClass() {
//SubClass constructor code goes here
}
//Inherit the methods of BaseClass
SubClass.prototype = new BaseClass();
//Override the parent's getName method
SubClass.prototype.getName = function() {
return "SubClass";
}
//Alerts "SubClass"
alert(new SubClass().getName());
// 运行时的JavaScript Class 定义和继承
// 看上去很传统,但这些脚本会导致在Internet Explorer中的内存泄漏.
function BaseClass() {
this.getName = function() {
return "BaseClass";
};
//BaseClass constructor code goes here
}
function SubClass() {
//在对象实例建立时重载父类的getName方法
this.getName = function() {
return "SubClass";
}
//SubClass constructor code goes here
}
//Inherit the methods of BaseClass
SubClass.prototype = new BaseClass();
//Alerts "SubClass"
alert(new SubClass().getName());
function BaseClass() { }
BaseClass.prototype.getName = function() {
return "BaseClass(" + this.getId() + ")";
}
BaseClass.prototype.getId = function() {
return 1;
}
function SubClass() {}
SubClass.prototype = new BaseClass();
SubClass.prototype.getName = function() {
//调用父类的getName()方法
//哈哈,这是对父类调用的直接引用吗?
return "SubClass(" + this.getId() + ") extends " +
BaseClass.prototype.getName();
}
SubClass.prototype.getId = function() {
return 2;
}
//输出结果:"SubClass(2) extends BaseClass(1)";
//这是正确的输出吗?
alert(new SubClass().getName());
function BaseClass() { }
BaseClass.prototype.getName = function() {
return "BaseClass(" + this.getId() + ")";
}
BaseClass.prototype.getId = function() {
return 1;
}
function SubClass() {}
SubClass.prototype = new BaseClass();
SubClass.prototype.getName = function() {
//一点魔法加上多态性!
//但很明显,这还是一个直接引用!
return "SubClass(" + this.getId() + ") extends " +
BaseClass.prototype.getName.call(this);
}
SubClass.prototype.getId = function() {
return 2;
}
//输出结果:"SubClass(2) extends BaseClass(2)";
//Hey, 我们得到了正确的输出!
alert(new SubClass().getName());
//Crockford的方法:给所有的function都增加'inherits' 方法、
//每个类都增加了'uber'方法来调用父类方法
Function.prototype.inherits = function(parent) {
var d = 0, p = (this.prototype = new parent());
this.prototype.uber = function(name) {
var f, r, t = d, v = parent.prototype;
if (t) {
while (t) {
v = v.constructor.prototype;
t -= 1;
}
f = v[name];
} else {
f = p[name];
if (f == this[name]) {
f = v[name];
}
}
d += 1;
r = f.apply(this, Array.prototype.slice.apply(arguments, [1]));
d -= 1;
return r;
};
};
function BaseClass() { }
BaseClass.prototype.getName = function() {
return "BaseClass(" + this.getId() + ")";
}
BaseClass.prototype.getId = function() {
return 1;
}
function SubClass() {}
SubClass.inherits(BaseClass);
SubClass.prototype.getName = function() {
//这里看上去非常的清晰,它调用了BaseClass的getName()方法
return "SubClass(" + this.getId() + ") extends " +
this.uber("getName");
}
SubClass.prototype.getId = function() {
return 2;
}
function TopClass() {}
TopClass.inherits(SubClass);
TopClass.prototype.getName = function() {
//这里看上去非常的清晰,它调用了SubClass的getName()方法
return "TopClass(" + this.getId() + ") extends " +
this.uber("getName");
}
TopClass.prototype.getId = function() {
//Ok, 因此this.getId()应该总是
//返回调用SubClass的getId()方法的返回值(2)。
return this.uber("getId");
}
//输出结果:"TopClass(2) extends SubClass(1) extends BaseClass(1)"
//嗯?后面的两次this.getId()调用都没有返回2.
//发生了什么?
alert(new TopClass().getName());
//定义最顶级类
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());
//定义最顶级类
function Class() { }
Class.prototype.construct = function() {};
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.$ = superClass;
proto[n] = item;
}
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 " +
arguments.callee.$.getName.call(this);
},
getId: function() {
return 2;
}
});
var TopClass = SubClass.extend({
getName: function() {
//调用SubClass的getName()方法
return "TopClass(" + this.getId() + ") extends " +
arguments.callee.$.getName.call(this);
},
getId: function() {
// this.getId()总是返回调用父类的getId()方法的返回值(2)
return arguments.callee.$.getId.call(this);
}
});
//输出结果:"TopClass(2) extends SubClass(2) extends BaseClass(2)"
//工作正常!而且没有任何中间function
alert(new TopClass().getName());