我只能简化到如此地步了 感觉还差一点没想到  大家都看看 帮小弟指点迷津 
Class.wrap=function(self, key, method){

return function(){//
var caller = this.caller, current = this._current;

this.caller = current; this._current = arguments.callee;
var result = method.apply(this, arguments);
this._current = current; this.caller = caller;
return result;
}
}
var a=function(){}
var b=function(){}
b.prototype.b=Class.wrap(this,'b',function(){this.p()})
b.prototype.p=Class.wrap(this,'p',function(){alert(this.caller)})
var bb=new b
bb.b()

解决方案 »

  1.   

    不好意思 上面有弹出错误 
    再简化一下 
    var w=function( method){

    return function(){//
    var caller = this.caller, current = this._current;

    this.caller = current; this._current = arguments.callee;
    var result = method.apply(this, arguments);
    this._current = current; this.caller = caller;
    return result;
    }
    }
    var a=function(){}
    var b=function(){}
    b.prototype.b=w(function(){this.p()})
    b.prototype.p=w(function(){alert(this.caller)})
    var bb=new b
    bb.b()
    这次可以正确弹出
      

  2.   

    下面的代码好像实现了 调用a同名函数的目的 也就是java中的 this.parent()功能
    有不对的地方 还请大家指点
    Function.prototype.extend=function(x){
    for(var i in x)this[i]=x[i]
    return this
    }var w=function(self, key, method){

    return function(){//
    var caller = this.caller, current = this._current;

    this.caller = current; this._current = arguments.callee;
    var result = method.apply(this, arguments);
    this._current = current; this.caller = caller;
    return result;
    }.extend({_owner: self, _origin: method, _name: key});
    }
    var a=function(){}
    a.prototype.b=w(this,'b',function(){alert('ssss')})//想调用a的这个同名函数  
    var b=function(){
    var b=function(){}
    b.parent =a;
    b.prototype = new a;
    b.prototype.parent=w(this,'parent',function(){
    var name = this.caller._name, previous = this.caller._owner.parent.prototype[name];
    if (!previous) throw new Error('The method "' + name + '" has no parent.');
    return previous.apply(this, arguments);
    })

    return b
    }
    b.prototype.b=w(this,'b',function(){this.parent()})//这里调用a的同名函数   var bb=new b
    var bbb=new bb
    bbb.b()//弹出ssss
      

  3.   


    这个问题和昨天的问题有点不同吧.
    关键是method传了进去.而且他是同一Function型的不同实体.
    通过apply(this)把第一次的方法对象塞给了后续的方法对象.
    而昨天的,你apply的是另一个方法.没把前面赋值的执行.等等我把运行顺序详细的说一下.
      

  4.   

    1.首先
    你在
    var bb=new b
    前加上
    alert(b.prototype.b)
    alert(b.prototype.p)
    你会发现他们返回的方法描述是一样的.
    但是内部是有差别的.
    他们的method对象是不同的.
    你可以在w的返回函数中alert一下就知道了.
      

  5.   

    2.之后是运行顺序.

    var result = method.apply(this, arguments);
    前后分别加上
    alert(method)
    你可以看到结果:
    function(){this.p()}(原型属性b的方法)
    function(){alert(this.caller)}(原型属性p的方法)
    function(){alert(this.caller)}
    function(){this.p()}所以在method.apply的同时.原型属性b的方法实际上是停止了的.
    所以过程变量是依旧存在的.
      

  6.   

    3.观测变量变化在下列两句分别加上alert
    var caller = this.caller, current = this._current;
                alert("caller\n" + this.caller)
                alert("_current\n" + this._current)
    this.caller = current; this._current = arguments.callee;
                alert("caller\n" + this.caller)
                alert("_current\n" + this._current) 你会发现.第一步执行原型属性b的时候.
    实际上能赋得值的是this._current
    所以.在中断,并以b方法属性继续执行p的时候.
    this._current实际上是拥有b方法的callee的
    所以在做赋值的时候
    this.caller得到的值得实际上就是current得到的this._current的值所以在执行p的参数方法时.就能打出this.caller的值了.
      

  7.   

    在2楼的那段代码 有些错误  你会发现 其实你注释掉Function.prototype.extend=function(x){
    for(var i in x)this[i]=x[i]
    return this
    }var w=function(self, key, method){

    return function(){//
    var caller = this.caller, current = this._current;

    this.caller = current; this._current = arguments.callee;
    var result = method.apply(this, arguments);
    this._current = current; this.caller = caller;
    return result;
    }.extend({_owner: self, _origin: method, _name: key});
    }
    var a=function(){}
    a.prototype.b=w(this,'b',function(){alert('ssss')})
    var b=function(){
    var b=function(){}
    //b.parent =a;
    b.prototype = new a;
    b.prototype.parent=w(this,'parent',function(){
    var name = this.caller._name, previous = this.caller._owner.parent.prototype[name];
    if (!previous) throw new Error('The method "' + name + '" has no parent.');
    return previous.apply(this, arguments);
    })
    b.prototype.b=w(this,'b',function(){this.parent();alert("aa");})//<-----上面注释掉这句 也可以执行 其实上面就没调用这句 直接调用的a的方法

    return b
    }
    b.prototype.parent =a;//加在这了 var bb=new b
    var bbb=new bb
    bbb.b()//先弹出ssss再弹出aa才是对的  这样保证肯定是调用的b的b(b里面调用的a)接下来 我会用更通俗的方法  替代这个方法
      

  8.   

    不过你注释不注释好像都没什么关系...
    因为你调用实际是w(this,'b',function(){this.parent();alert("aa");})的返回值.继续关注.
      

  9.   

    看一个东西 
    var a=function(){
    var b=function(){}
    b.prototype.b=this.w//
    return b//这里这个函数的this丢失了
    }
    a.prototype.w="wwww"
    var aa=new a
    var aaa=new aa
    alert(aaa.b)//弹出wwww但是我上面的那些例子  却把this保存了下来  保存在了相应函数的_owner属性中这就能解释this.caller._owner.parent.prototype[name]; 这句话为什么能调用到a函数的方法的原因
      

  10.   

    return b//这里这个函数的this丢失了你的这句是什么意思?
      

  11.   

    var a=function(){
    var b=function(){}
    alert(this.w)//this有w
    return b//
    }
    a.prototype.w="wwww"
    var aa=new a
    alert(aa.w)//弹出undefined aa其实是b函数 而不是new a生成的this,所以this丢失了,a.prototype.w也丢失了,所以aa.w弹出undefined
      

  12.   

    额...你上面把这句丢了...
    b.prototype.b=this.w
    我说怎么老调不对...a.prototype.w没有丢吧.付给了b了.没错aa是b函数.但不是实例.而且你赋值的值是给了b的.不是w...
    在实例中才有原型属性的.你试下:function a(){}
    a.prototype.a="www"
    alert(a.a)
    alert(new a().a)运行中的方法中.this也算是一个实例.
      

  13.   

    @13 其实都是一个意思 我说的是this相对于var aa=new a中的aa丢失了
     
    下面的代码其实和mootools的Class.js已经非常像了 使用这种方法 可以很简单的实现类继承function $type(x){
    if(typeof x=='object'){
    if(x instanceof Array){
    return 'array'
    }else if(x instanceof Function){
    return 'function'
    }else{
    return 'object'
    }
    }else{
    return typeof x
    }
    }Function.prototype.extend=function(x){
    for(var i in x)this[i]=x[i]
    return this
    }var Class=function(params){
    var newClass = function(){}.extend(this);//赋予Class.prototype上的方法 ,其实就是继承了Class的implement方法

    newClass.implement(params);//
    return newClass;}Class.wrap=function(self, key, method){

    return function(){//
    var caller = this.caller, current = this._current;

    this.caller = current; this._current = arguments.callee;
    var result = method.apply(this, arguments);
    this._current = current; this.caller = caller;
    return result;
    }.extend({_owner: self, _origin: method, _name: key});
    }Class.prototype.implement= function(key, value){//

    if ($type(key) == 'object'){
    for (var p in key) this.implement(p, key[p]);//p=options key[p]={}
    return this;
    }

    var mutator = Class.Mutators[key];

    if (mutator){
    value = mutator.call(this, value);
    if (value == null) return this;
    }

    var proto = this.prototype;//变更proto就变更了newClass.prototype switch ($type(value)){

    case 'function':
    if (value._hidden) return this;
    proto[key] = Class.wrap(this, key, value);//return function(){}.extend()
    break;

    default: proto[key] = value;//newClass.prototype[key]=value }

    return this; }

    Class.Mutators = {

    Extends: function(parent){ this.parent = parent;
    this.prototype = new parent; this.implement('parent', function(){
    var name = this.caller._name, previous = this.caller._owner.parent.prototype[name];
    if (!previous) throw new Error('The method "' + name + '" has no parent.');
    return previous.apply(this, arguments);
    }); }

    };//下面就可以这样调用了
    var a=new Class({
    a:function(){alert("aaaa")},
    b:function(){alert(("bbbb"))},
    c:function(x){alert(x)}
    })
    var b=new Class({
    Extends:a,//Extends要写在第一个
    b:function(){alert("b22222")},
    c:function(){this.parent(33)}
    })
    var bb=new b
    bb.a()//aaaa
    bb.b()//b22222
    bb.c()//33
      

  14.   

    在8楼那  虽然能正确弹出 但是却把方法绑定在了window上 
    下面这个更符合封装的特性  也更符合逻辑 
    Function.prototype.extend=function(x){
        for(var i in x)this[i]=x[i]
        return this
    }var w=function(self, key, method){
            
            return function(){//
                var caller = this.caller, current = this._current;
                
                this.caller = current; this._current = arguments.callee;
                var result = method.apply(this, arguments);
                this._current = current; this.caller = caller;
                return result;
            }.extend({_owner: self, _origin: method, _name: key});
        }
        var a=function(){}var b=function(){
        var b=function(){}
        a.prototype.b=w(b,'b',function(){alert('ssss')})//this-->改成了b
    b.parent =a;
    b.prototype = new a;
    b.prototype.b=w(b,'b',function(){this.parent();alert("aa");})//this-->改成了b
    b.prototype.parent=w(b, 'parent', function(){////this-->改成了b
    var name = this.caller._name, previous = this.caller._owner.parent.prototype[name];
    if (!previous) 
    throw new Error('The method "' + name + '" has no parent.');
    return previous.apply(this, arguments);
    })

        
        return b
    }var bb=new b
    var bbb=new bb
    bbb.b()//先弹出ssss再弹出aa  
      

  15.   

    好兴奋 短短几行代码 实现14楼同样功能
    Function.prototype.extend=function(x){
        for(var i in x)this[i]=x[i]
        return this
    }var w=function(self, key, method){
            
            return function(){//
                var caller = this.caller, current = this._current;
                
                this.caller = current; this._current = arguments.callee;
                var result = method.apply(this, arguments);
                this._current = current; this.caller = caller;
                return result;
            }.extend({_owner: self, _origin: method, _name: key});
        }var Class = function(params){
    var b = function(){}
    for (var p in params) {
    if (p == 'Extends'){
    var parent = params[p];

    b.parent = parent;
    b.prototype = new parent;
    b.prototype.parent = w(b, 'parent', function(){//
    var name = this.caller._name, previous = this.caller._owner.parent.prototype[name];
    if (!previous) 
    throw new Error('The method "' + name + '" has no parent.');
    return previous.apply(this, arguments);
    })
    continue
    }
    b.prototype[p] = w(b, p, params[p])
    }
    return b
    }var a=new Class({
        a:function(){alert("aaaa")},
        b:function(){alert(("bbbb"))},
        c:function(x){alert(x)}
    })
    var b=new Class({
        Extends:a,//Extends要写在第一个
        b:function(){alert("b22222")},
        c:function(){this.parent(33)}
    })
    var bb=new b
    bb.a()//aaaa
    bb.b()//b22222
    bb.c()//33
      

  16.   

    下面增加了对object 和array的支持 有不对的地方 还请大家指点
    function $type(x){
    if(typeof x=='object'){
    if(x instanceof Array){
    return 'array'
    }else if(x instanceof Function){
    return 'function'
    }else{
    return 'object'
    }
    }else{
    return typeof x
    }
    }function $unlink(object){
    var unlinked;
    switch ($type(object)){
    case 'object':
    unlinked = {};
    for (var p in object) unlinked[p] = $unlink(object[p]);
    break;
    case 'array':
    unlinked = [];
    for (var i = 0, l = object.length; i < l; i++) unlinked[i] = $unlink(object[i]);
    break;
    default: return object;
    }
    return unlinked;
    };function $mixin(mix){//mix=混合
    for (var i = 1, l = arguments.length; i < l; i++){
    var object = arguments[i];
    if ($type(object) != 'object') continue;
    for (var key in object){
    var op = object[key], mp = mix[key];
    mix[key] = (mp && $type(op) == 'object' && $type(mp) == 'object') ? $mixin(mp, op) : $unlink(op);
    }
    }
    return mix;
    };
    Function.prototype.extend=function(x){
        for(var i in x)this[i]=x[i]
        return this
    }var wrap=function(self, key, method){//包裹起来
            
            return function(){//
                var caller = this.caller, current = this._current;
                
                this.caller = current; this._current = arguments.callee;
                var result = method.apply(this, arguments);
                this._current = current; this.caller = caller;
                return result;
            }.extend({_owner: self, _origin: method, _name: key});
        }var Class = function(params){
    var b = function(){}
    for (var p in params) {
    value=params[p]
    switch ($type(value)) {
    case 'function':
    if (p == 'Extends') {
    b.parent = value;
    b.prototype = new value;
    b.prototype.parent = wrap(b, 'parent', function(){//
    var name = this.caller._name, previous = this.caller._owner.parent.prototype[name];
    if (!previous) 
    throw new Error('The method "' + name + '" has no parent.');
    return previous.apply(this, arguments);
    })
    continue
    }
    b.prototype[p] = wrap(b, p, params[p])
    break;
    case 'object':
    var previous = b.prototype[p];//
    if ($type(previous) == 'object') $mixin(previous, value);
    else b.prototype[p] = $unlink(value);
    break;

    case 'array':
    b.prototype[p] = $unlink(value);
    break;

    default: b.prototype[p] = value;
    }
    }
    return b
    }var a=new Class({
        a:function(){alert("aaaa")},
        b:function(){alert(("bbbb"))},
        c:function(x){alert(x)},
    d:{a:"aaa"}
    })
    var b=new Class({
        Extends:a,//Extends要写在第一个
        b:function(){alert("b22222")},
        c:function(x){this.parent(x)},
    d:{b:"bbb"}
    })
    var c=new Class({
    Extends:b,
    c:function(){this.parent(33)},
    d:{c:"ccc"}
    })
    var cc=new c
    cc.a()//aaaa
    cc.b()//b22222
    cc.c()//33
    alert(cc.d.a+' '+cc.d.b+' '+cc.d.c)//aaa,bbb,ccc