Function.prototype.method = function(name, func) { this.prototype[name] = func; return this; }; // A (rather complex) function that allows you to gracefully inherit // functions from other objects and be able to still call the 'parent' // object's function Function.method('inherits', function(parent) { // Keep track of how many parent-levels deep we are var depth = 0; // Inherit the parent's methods var proto = this.prototype = new parent(); // Create a new 'priveledged' function called 'uber', that when called // executes any function that has been written over in the inheritance this.method('uber', function uber(name) { var func; // The function to be execute var ret; // The return value of the function var v = parent.prototype; // The parent's prototype // If we're already within another 'uber' function if (depth) { // Go the necessary depth to find the orignal prototype for ( var i = d; i > 0; i += 1 ) { v = v.constructor.prototype; } // and get the function from that prototype func = v[name]; // Otherwise, this is the first 'uber' call } else { // Get the function to execute from the prototype func = proto[name]; // If the function was a part of this prototype if ( func == this[name] ) { // Go to the parent's prototype instead func = v[name]; } } // Keep track of how 'deep' we are in the inheritance stack depth += 1; // Call the function to execute with all the arguments but the first // (which holds the name of the function that we're executing) ret = func.apply(this, Array.prototype.slice.apply(arguments, [1])); // Reset the stack depth depth -= 1; // Return the return value of the execute function return ret; }); return this; });
for ( var i = d; i > 0; i += 1 ) { v = v.constructor.prototype; }
for ( var i = d; i > 0; i += 1 ) {
v = v.constructor.prototype;
}
循环的作用是将v指向最初的原型。
var i = d; i > 0; i += 1
d在哪定义呢?
是不是已经发过一个一摸一样的问题的。。。。
[code="java"] for ( var i = d; i > 0; i += 1 ) {
v = v.constructor.prototype;
}[/code]
应该是 i = depth 吧
[code="java"]Function.prototype.method = function (name, func) {
this.prototype[name] = func;
return this;
};
Function.method('inherits', function (parent) {
var d = {}, // 递归调用时的计数器
// 下面这行已经完成了最简单的原型继承:将子类的prototype设为父类的实例
p = (this.prototype = new parent());
// 下面给子类增加uber方法(类似Java中的super方法),以调用上层继承链中的方法
this.method('uber', function uber(name) {
if (!(name in d)) {
d[name] = 0;
}
var f, r, t = d[name], 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];
}
}
// 因为f函数中,可能存在uber调用上层的f
// 不设置d[name]的话,将导致获取的f始终为最近父类的f(陷入死循环)
d[name] += 1;
// slice.apply的作用是将第2个及其之后的参数转换为数组
// 第一个参数就是f的名字,无需传递
// 这样,通过uber调用上层方法时可以传递参数:
// sb.uber(methodName, arg1, arg2, ...);
r = f.apply(this, Array.prototype.slice.apply(arguments, [1]));
// 还原计数器
d[name] -= 1;
return r;
});
// 返回this, 方便chain操作
return this;
});
[/code]
可以参考:
[code="java"]
Function.method('inherits', function (parent) {
// 关键是这一段:this.prototype = new parent(),这里实现了原型的引用
var d = {}, p = (this.prototype = new parent());
// 只为子类的原型增加uber方法,这里的Closure是为了在调用uber函数时知道当前类的父类的原型(也即是变量 - v)
this.method('uber', function uber(name) {
// 这里考虑到如果name是存在于Object.prototype中的函数名的情况
// 比如 "toString" in {} === true
if (!(name in d)) {
// 通过d[name]计数,不理解具体的含义
d[name] = 0;
}
var f, r, t = d[name], v = parent.prototype;
if (t) {
while (t) {
v = v.constructor.prototype;
t -= 1;
}
f = v[name];
} else {
// 个人觉得这段代码有点繁琐,既然uber的含义就是父类的函数,那么f直接指向v[name]就可以了
f = p[name];
if (f == this[name]) {
f = v[name];
}
}
d[name] += 1;
// 执行父类中的函数name,但是函数中this指向当前对象
// 同时注意使用Array.prototype.slice.apply的方式对arguments进行截断(因为arguments不是标准的数组,没有slice方法)
r = f.apply(this, Array.prototype.slice.apply(arguments, [1]));
d[name] -= 1;
return r;
});
return this;
});
[/code]
[code="java"]
for ( var i = d; i > 0; i += 1 ) {
v = v.constructor.prototype;
}
[/code]
逐层遍历,循环的作用是将v指向最初的原型