2012-04-26 60 views
0

我有三个支柱的看法是这样的:骨干观的继承到孙级

ParentView = Backbone.View.extend({ 
    addUsers : function() 
    { 
     console.log("Parent's Add User"); 
    }, 

    addProject : function() 
    { 
     console.log("Parent's Add Project"); 
    } 
}); 

ChildView = ParentView.extend({ 
    addProject : function() 
    { 
     var self = this; 

     console.log("Child's add Project"); 

     self.constructor.__super__.addProject.apply(self); 
    } 
}); 

GrandChildView = ChildView.extend({ 
    addItem : function() 
    { 
     var self = this; 
     self.addProject(); 
    }, 

    addUsers : function() 
    { 
     var self = this; 
     console.log("Grand Child's Add users"); 
     self.constructor.__super__.addUsers.apply(self); 
    } 
}); 

var vChild = new ChildView(); 
vChild.addProject(); // works fine, by calling it own and parent's functions. 

var vGrandChild = new GrandChildView(); 
vGrandChild.addUsers(); // This throws Maximum call stack size exceeded error, 

当我创建GrandChildView的新实例,然后调用其ADDUSERS方法,它引发的最大堆栈大小超过了,我想这是监守它一直在呼唤自己。但无法弄清楚。 原因似乎是调用super的方法。

谢谢。

+0

我觉得你在用JS中的'super'玩火。 – fguillen 2012-04-26 18:46:21

回答

1

什么你实际上在做,你应该能够理解,如果你真的按照你的功能的步骤调用确实是一个无限循环调用的“大孩子”的观点:)

提示:这是值得演习想什么this是因为你每次apply ....;)

否则这可能是你的意思是要达到什么:

ParentView = Backbone.View.extend({ 
    addUsers : function() 
    { 
     console.log("Parent's Add User"); 
    }, 

    addProject : function() 
    { 
     console.log("Parent's Add Project"); 
    } 
}); 

ChildView = ParentView.extend({ 
    addProject : function() 
    { 
     console.log("Child's add Project"); 

     ParentView.prototype.addProject.call(this); 
    } 
}); 

GrandChildView = ChildView.extend({ 

    addItem : function() 
    { 
     this.addProject(); 
    }, 

    addUsers : function() 
    { 
     console.log("Grand Child's Add users"); 
     ChildView.prototype.addUsers.call(this); 
    } 
}); 

var vChild = new ChildView(); 
vChild.addProject(); // works fine, by calling it own and parent's functions. 

var vGrandChild = new GrandChildView(); 
vGrandChild.addUsers(); 
+0

我同意你的观点,我有很多意见要像这样继承,如果用你建议的方法行事,你能建议吗?例如,将“ChildView.protoype”指定给扩展它的视图。就像你在GrandChildView的addUsers中提到的一样。 – Chetan 2012-04-27 05:57:24

+0

是的使用原型将始终工作。避免超级不惜一切代价。 – ggozad 2012-04-27 08:36:57

0

只是为了尝试:添加到您的ChildView:

addUsers : function() 
{ 
    var self = this; 
    console.log("Child's Add users"); 
    self.constructor.__super__.addUsers.apply(self); 
} 

也许作为addUsers不能正常发挥在ChildView.prototype定义,但它是继承则没有发现在self.prototype是中继。我不知道......就像我说的,我不认为JS是用这种方式继承的意思,因为它是面向对象语言的通用

+0

不,这不起作用,因为它仍然会无限循环。 – Chetan 2012-04-27 05:54:37

0

我把你的代码,转换为CoffeeScript的,它给了我这个JavaScript,它适用于我:

var ChildView, GrandChildView, ParentView, 
    __hasProp = {}.hasOwnProperty, 
    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }, 
    __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; 

ParentView = (function(_super) { 

    __extends(ParentView, _super); 

    ParentView.name = 'ParentView'; 

    function ParentView() { 
    return ParentView.__super__.constructor.apply(this, arguments); 
    } 

    ParentView.prototype.addUsers = function() { 
    return console.log("Parent's Add User"); 
    }; 

    ParentView.prototype.addProject = function() { 
    return console.log("Parent's Add Project"); 
    }; 

    return ParentView; 

})(Backbone.View); 

ChildView = (function(_super) { 

    __extends(ChildView, _super); 

    ChildView.name = 'ChildView'; 

    function ChildView() { 
    this.addProject = __bind(this.addProject, this); 
    return ChildView.__super__.constructor.apply(this, arguments); 
    } 

    ChildView.prototype.addProject = function() { 
    console.log("Child's add Project"); 
    return ChildView.__super__.addProject.apply(this, arguments); 
    }; 

    return ChildView; 

})(ParentView); 

GrandChildView = (function(_super) { 

    __extends(GrandChildView, _super); 

    GrandChildView.name = 'GrandChildView'; 

    function GrandChildView() { 
    this.addUsers = __bind(this.addUsers, this); 

    this.addItem = __bind(this.addItem, this); 
    return GrandChildView.__super__.constructor.apply(this, arguments); 
    } 

    GrandChildView.prototype.addItem = function() { 
    return this.addProject(); 
    }; 

    GrandChildView.prototype.addUsers = function() { 
    console.log("Grand Child's Add users"); 
    return GrandChildView.__super__.addUsers.apply(this, arguments); 
    }; 

    return GrandChildView; 

})(ChildView); 

从我的理解棘手的问题是你是绑定这个自我内部的函数。这种情况在您每次调用具有您调用函数的上下文的函数时都会发生,这正是您想要省略的。你需要在一个函数中绑定这个函数,就像你通常只用于回调函数一样,或者你没有引用你正在调用该函数的对象的情况,只是对该函数的引用。所以如果你需要绑定这样的情况下做这个功能以外。