在保持对象引用和inheritance的同时组织原型JavaScript

我使用JavaScript原型和inheritance构build了一个大型应用程序。 但是我很难组织我的代码。 例如,我有一个类的传送带,它有很多这样的function:

Carousel.prototype.next = function () {...} Carousel.prototype.prev = function () {..} Carousel.prototype.bindControls = function () {..} 

我想像这样组织我的代码:

 Carousel.prototype.controls = { next: function () { ... } , prev: function() { ... }, bindControls: function () { .. } } 

但这会导致“这个”的价值被丢失。 我可以跟踪它使用一个全局的实例,但这会导致问题时,类inheritance例如在另一个文件中,我有这样的事情来重写父类

 BigCarousel.prototype.next = function () {...} 

我的inheritance是这样完成的:

 Function.prototype.inheritsFrom = function (parentClass) { if (parentClass.constructor === Function) { //Normal Inheritance this.prototype = $.extend(this.prototype , new parentClass); this.prototype.constructor = this; this.prototype.parent = parentClass.prototype; } else { //Pure Virtual Inheritance this.prototype = $.extend(this.prototype, parentClass); this.prototype.constructor = this; this.prototype.parent = parentClass; } return this; }; 

所以我可以这样做:

 BigCarousel.inheritsFrom(Carousel) 

有谁知道我该如何解决“这个”的价值?

你可以使Controls成为它自己的类:

 var Controls = function (controllable_object) { this.ref = controllable_object; }; Controls.prototype.next = function () { this.ref.foo(); } // .. var Carousel = function () { this.controls = new Controls(this); }; // .. 

这不允许你重写Controls的实现。 随着更多的dependency injection,你会得到像这样的东西:

 var Controls = function (controllable_object) { this.ref = controllable_object; }; Controls.prototype.next = function () { this.ref.foo(); } // .. var Carousel = function () { this.controllers = []; }; Carousel.prototype.addController = function (controller) { this.controllers.push(controller); }; // .. var carousel = new Carousel(); carousel.addController(new Controls(carousel)); 

我的inheritance是这样完成的:

 $.extend(this.prototype , new parentClass); 

哎哟。 这不是inheritance(与new BigCarousel instanceof Carousel ),而只是复制属性。 也许这对你来说已经够了,但是你应该把它叫做mixin 。 此外,你应该避免使用new的inheritance 。


但这会导致“这个”的价值被丢失。 我该如何解决这个问题?

对于具有嵌套属性的父对象来说,这是不可能的(只要你不想每次都明确地设置它)。 你只有两个select:

  • 忘记它,并通过为它们加上前缀来组织你的方法( controlNextcontrolBind ,…)
  • 给你的每个传送带自己的controls对象。 为了inheritance,例如使它们成为CarouselControls实例。 如果这些控件与旋转木马相当独立,并且不需要访问它们随处可见的旋转木马,则这特别适合。 如果他们不是,你仍然可以传递一个引用到父转盘到他们的构造函数中,例如:

     this.controls = new CarouselControls(this); 

    此外,为了在不同的轮播中定制控件,您可能还必须BigCarousel CarouselControls ,或者您准备Controls对象来为一般的不同轮播服务,所以从BigCarousel可以

     Carousel.call(this); // make this a carousel this.controls.activate({big: true, fast: false}); // or something 

您可以使用Function的.bind方法。

在Javascript函数从Objectinheritance,所以他们有自己的方法。 其中一种方法是.bind:

https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind

还有,你正在做inheritance错误,正确的方式与原始的Javascript是:

 ChildClass= function() { ParentClass.apply(this, arguments); //calling parent constructor //constructor }; ChildClass.prototype= new ParentClass(); 

那么你可以简单地在你的构造函数上做这件事:

 Courossel= function() { ParentClass.apply(this, arguments); //calling parent constructor this.controls.next.bind(this); this.controls.prev.bind(this); this.controls.bindControls.bind(this); } 

但我不得不说,Frits的build议是更好的,使控制自己的类,并在Carousel构造函数实例化它传递给您的Carousel实例(this关键字)的引用。 只是不要把它称为“.ref”,这是混乱。