在保持对象引用和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:
- 忘记它,并通过为它们加上前缀来组织你的方法(
controlNext
,controlBind
,…) -
给你的每个传送带自己的
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”,这是混乱。