但是我很难组织代码。
例如,我有一个类轮播,它具有许多类似这样的功能:
Carousel.prototype.next = function () {...}
Carousel.prototype.prev = function () {..}
Carousel.prototype.bindControls = function () {..}
我想这样组织我的代码:
Carousel.prototype.controls = {
next: function () { ... } ,
prev: function() { ... },
bindControls: function () { .. }
}
但是这将导致“ this”的值丢失。我可以使用全局实例来跟踪它,但是例如在继承该类时,这会引起问题。在另一个文件中,我有类似这样的东西来覆盖父类>我的继承是这样完成的:
BigCarousel.prototype.next = function () {...}
所以我可以做:
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;
};
有人知道吗如何解决“ this”值?
#1 楼
您可以使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
的实现。有了更多的依赖注入,您将得到类似: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));
评论
这似乎是最合乎逻辑的事情,但是可以说我有很多处理轮播项目的功能,它们也应该属于自己的班级吗?例如:Carousel.prototype.getItemsPassed = function(){...} Carousel.prototype.setItemsPassed = function(){...} Carousel.prototype.getThumbData = function(){...} Carousel.prototype.setThumbData =函数(){...}
–尼玛
13年4月8日在17:26
也许,对于控件而言,分解是有意义的,但肯定不是您一直想要的。只需遵循面向对象和继承设计的一般准则即可。
–太平
13年4月8日在18:40
#2 楼
我的继承是这样完成的:
$.extend(this.prototype , new parentClass);
很好。这不是继承(使用
new BigCarousel instanceof Carousel
),而只是复制属性。也许这对您来说已经足够了,但是您应该将其称为mixin。另外,您应该避免使用new
进行继承。但这会导致丢失“ this”的值。我该如何解决?
不可能
this
指向具有嵌套属性的父对象(只要您不想每次都明确地设置它)。您只有两种选择:忘记它,并通过给它们加上前缀(
controlNext
,controlBind
…)来组织您的方法让每个轮播都自己拥有
controls
对象。为了继承,请使其成为CarouselControls
实例。如果这些控件与轮播非常独立,并且不需要访问随处可见的轮播,则特别适合。如果不是,您仍然可以将对父轮播的引用传递到其构造函数中,例如:this.controls = new CarouselControls(this);
此外,为了自定义不同轮播中的控件,您可能必须也必须继承
CarouselControls
的子类-或者您准备好Controls
对象以通常用于不同的轮播,以便从BigCarousel
您可以Carousel.call(this); // make this a carousel
this.controls.activate({big: true, fast: false}); // or something
评论
谢谢您的注意,我已经意识到了这一点,但目前浅表副本可以正常工作,我无法正确进行多重继承,例如:Carousel.inheritsFrom(Base)Carousel.inheritsFrom(Images)
–尼玛
13年4月8日在17:22
好的,是的,对于多重继承,您需要使用此类mixin。只有设置单个父属性才没有意义:-)
–贝尔吉
13年4月8日在17:34
#3 楼
您可以使用Function的.bind方法。在Javascript函数中继承自Object,因此它们具有自己的方法。这些方法之一是.bind:
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind
也如果您做的继承错误,那么使用原始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建议更好,使控件成为自己的类,并在Carousel构造函数上实例化它,传递对您的Carousel实例的引用(this关键字)。只是不要称它为“ .ref”,这很令人困惑。
评论
另请参见原型:深入了解实例上下文的上下文